├── Podfile ├── .swift-version ├── Sources ├── CRuntime │ ├── dummy.c │ ├── include │ │ ├── module.modulemap │ │ └── CRuntime.h │ └── CMakeLists.txt ├── CMakeLists.txt └── Runtime │ ├── Runtime.h │ ├── Layouts │ ├── EnumTypeDescriptor.swift │ ├── ProtocolTypeContainer.swift │ ├── EnumMetadataLayout.swift │ ├── FunctionMetadataLayout.swift │ ├── StructMetadataLayout.swift │ ├── ProtocolMetadataLayout.swift │ ├── ClassHeader.swift │ ├── MetadataLayoutType.swift │ ├── TupleMetadataLayout.swift │ ├── ProtocolDescriptor.swift │ ├── ExistentialContainter.swift │ ├── TargetTypeGenericContextDescriptorHeader.swift │ ├── StructTypeDescriptor.swift │ ├── TypeDescriptor.swift │ ├── ValueWitnessTable.swift │ ├── ClassTypeDescriptor.swift │ ├── ClassMetadataLayout.swift │ └── FieldDescriptor.swift │ ├── Models │ ├── TypeInfoConvertible.swift │ ├── Case.swift │ ├── Errors.swift │ ├── FunctionInfo.swift │ ├── PropertyInfo.swift │ ├── TypeInfo.swift │ └── Kind.swift │ ├── Metadata │ ├── ProtocolMetadata.swift │ ├── StructMetadata.swift │ ├── Metadata.swift │ ├── FuntionMetadata.swift │ ├── TupleMetadata.swift │ ├── MetadataType.swift │ ├── EnumMetadata.swift │ ├── NominalMetadataType.swift │ └── ClassMetadata.swift │ ├── Pointers │ ├── Union.swift │ ├── RelativeVectorPointer.swift │ ├── Vector.swift │ ├── RelativePointer.swift │ └── Pointers.swift │ ├── Utilities │ ├── String+Extensions.swift │ ├── RetainCounts.swift │ ├── GettersSetters.swift │ └── Pointer+Extensions.swift │ ├── CMakeLists.txt │ └── Factory │ ├── DefaultValue.swift │ └── Factory.swift ├── Resources ├── Runtime.png └── 80sRuntime.png ├── .swiftlint.yml ├── Tests ├── LinuxMain.swift └── RuntimeTests │ ├── Info.plist │ ├── ValueWitnessTableTests.swift │ ├── FactoryTests.swift │ ├── ValuePointerTests.swift │ ├── XCTestManifests.swift │ ├── MetadataTests.swift │ ├── GetSetClassTests.swift │ └── GetSetStructTests.swift ├── Runtime.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── project.pbxproj ├── CMakeLists.txt ├── Package.swift ├── Runtime.podspec ├── LICENSE ├── .gitignore ├── .github └── workflows │ └── tests.yml ├── Scripts └── TestCaseGen.py ├── README.md └── cmake └── modules └── SwiftSupport.cmake /Podfile: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 5.0 2 | -------------------------------------------------------------------------------- /Sources/CRuntime/dummy.c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Sources/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(CRuntime) 2 | add_subdirectory(Runtime) -------------------------------------------------------------------------------- /Resources/Runtime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wickwirew/Runtime/HEAD/Resources/Runtime.png -------------------------------------------------------------------------------- /Resources/80sRuntime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wickwirew/Runtime/HEAD/Resources/80sRuntime.png -------------------------------------------------------------------------------- /Sources/CRuntime/include/module.modulemap: -------------------------------------------------------------------------------- 1 | module CRuntime { 2 | header "CRuntime.h" 3 | export * 4 | } 5 | -------------------------------------------------------------------------------- /Sources/CRuntime/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(CRuntime STATIC 2 | dummy.c) 3 | 4 | target_include_directories(CRuntime PUBLIC 5 | include) -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | disabled_rules: 2 | - identifier_name 3 | - trailing_whitespace 4 | - cyclomatic_complexity 5 | included: 6 | - Sources 7 | -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import RuntimeTests 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += RuntimeTests.__allTests() 7 | 8 | XCTMain(tests) 9 | -------------------------------------------------------------------------------- /Runtime.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /Runtime.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Runtime.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | 3 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) 4 | 5 | project(Runtime 6 | LANGUAGES C Swift) 7 | 8 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) 9 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) 10 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 11 | set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift) 12 | 13 | include(SwiftSupport) 14 | 15 | add_subdirectory(Sources) 16 | 17 | export(EXPORT Runtime 18 | NAMESPACE Runtime:: 19 | FILE Runtime-config.cmake) -------------------------------------------------------------------------------- /Sources/Runtime/Runtime.h: -------------------------------------------------------------------------------- 1 | // 2 | // Runtime.h 3 | // Runtime 4 | // 5 | // Created by Wes Wickwire on 11/1/17. 6 | // Copyright © 2017 Wes Wickwire. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Runtime. 12 | FOUNDATION_EXPORT double RuntimeVersionNumber; 13 | 14 | //! Project version string for Runtime. 15 | FOUNDATION_EXPORT const unsigned char RuntimeVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | import PackageDescription 3 | let package = Package( 4 | name: "Runtime", 5 | products: [ 6 | .library( 7 | name: "Runtime", 8 | targets: ["Runtime"]) 9 | ], 10 | targets: [ 11 | .target( 12 | name: "Runtime", 13 | dependencies: ["CRuntime"]), 14 | .target( 15 | name: "CRuntime", 16 | dependencies: []), 17 | .testTarget( 18 | name: "RuntimeTests", 19 | dependencies: ["Runtime"]) 20 | ], 21 | swiftLanguageVersions: [.v5] 22 | ) 23 | -------------------------------------------------------------------------------- /Sources/CRuntime/include/CRuntime.h: -------------------------------------------------------------------------------- 1 | #ifndef cruntime_h 2 | #define cruntime_h 3 | 4 | #include 5 | 6 | const void * _Nullable swift_getTypeByMangledNameInContext( 7 | const char * _Nullable typeNameStart, 8 | int typeNameLength, 9 | const void * _Nullable context, 10 | const void * _Nullable const * _Nullable genericArgs); 11 | 12 | const void * _Nullable swift_allocObject( 13 | const void * _Nullable type, 14 | size_t requiredSize, 15 | size_t requiredAlignmentMask); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /Runtime.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | s.name = "Runtime" 4 | s.version = "2.2.7" 5 | s.summary = "Runtime" 6 | s.description = <<-DESC 7 | Runtime abilities for native swift objects. 8 | DESC 9 | s.homepage = "https://github.com/wickwirew/Runtime" 10 | s.license = "MIT" 11 | s.author = { "Wesley Wickwire" => "wickwirew@gmail.com" } 12 | s.ios.deployment_target = '12.0' 13 | s.tvos.deployment_target = '12.0' 14 | s.osx.deployment_target = '10.13' 15 | s.source = { :git => "https://github.com/wickwirew/Runtime.git", :tag => s.version } 16 | s.source_files = 'Sources/**/*.{swift,h}' 17 | end 18 | -------------------------------------------------------------------------------- /Tests/RuntimeTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/EnumTypeDescriptor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EnumTypeDescriptor.swift 3 | // Runtime 4 | // 5 | // Created by Wes Wickwire on 4/6/19. 6 | // 7 | 8 | struct EnumTypeDescriptor: TypeDescriptor { 9 | var flags: ContextDescriptorFlags 10 | var parent: RelativePointer 11 | var mangledName: RelativePointer 12 | var accessFunctionPointer: RelativePointer 13 | var fieldDescriptor: RelativePointer 14 | var numPayloadCasesAndPayloadSizeOffset: UInt32 15 | var numEmptyCases: UInt32 16 | var offsetToTheFieldOffsetVector: RelativeVectorPointer 17 | var genericContextHeader: TargetTypeGenericContextDescriptorHeader 18 | 19 | var numberOfFields: Int32 { 20 | get { return 0 } 21 | set { } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Wesley Wickwire 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Sources/Runtime/Models/TypeInfoConvertible.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | protocol TypeInfoConvertible { 24 | mutating func toTypeInfo() -> TypeInfo 25 | } 26 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/ProtocolTypeContainer.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct ProtocolTypeContainer { 24 | let type: Any.Type 25 | let witnessTable: Int 26 | } 27 | -------------------------------------------------------------------------------- /Sources/Runtime/Models/Case.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | /// An enum case 24 | public struct Case { 25 | public let name: String 26 | public let payloadType: Any.Type? 27 | } 28 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/EnumMetadataLayout.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct EnumMetadataLayout: NominalMetadataLayoutType { 24 | var _kind: Int 25 | var typeDescriptor: UnsafeMutablePointer 26 | } 27 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/FunctionMetadataLayout.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct FunctionMetadataLayout: MetadataLayoutType { 24 | var _kind: Int 25 | var flags: Int 26 | var argumentVector: Vector 27 | } 28 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/StructMetadataLayout.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct StructMetadataLayout: NominalMetadataLayoutType { 24 | var _kind: Int 25 | var typeDescriptor: UnsafeMutablePointer 26 | } 27 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/ProtocolMetadataLayout.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct ProtocolMetadataLayout: MetadataLayoutType { 24 | var _kind: Int 25 | var layoutFlags: Int 26 | var numberOfProtocols: Int 27 | var protocolDescriptorVector: UnsafeMutablePointer 28 | } 29 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/ClassHeader.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct ClassHeader { 24 | var isaPointer: Int 25 | var strongRetainCounts: Int32 26 | var weakRetainCounts: Int32 27 | } 28 | 29 | extension ClassHeader { 30 | 31 | static func size() -> Int { 32 | return MemoryLayout.size 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/MetadataLayoutType.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | protocol MetadataLayoutType { 24 | var _kind: Int { get set } 25 | } 26 | 27 | protocol NominalMetadataLayoutType: MetadataLayoutType { 28 | associatedtype Descriptor: TypeDescriptor 29 | var typeDescriptor: UnsafeMutablePointer { get set } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/Runtime/Metadata/ProtocolMetadata.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct ProtocolMetadata: MetadataType { 24 | 25 | var pointer: UnsafeMutablePointer 26 | 27 | mutating func mangledName() -> String { 28 | return String(cString: pointer.pointee.protocolDescriptorVector.pointee.mangledName) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sources/Runtime/Models/Errors.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | enum RuntimeError: Error { 24 | case couldNotGetTypeInfo(type: Any.Type, kind: Kind) 25 | case couldNotGetPointer(type: Any.Type, value: Any) 26 | case noPropertyNamed(name: String) 27 | case unableToBuildType(type: Any.Type) 28 | case errorGettingValue(name: String, type: Any.Type) 29 | } 30 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/TupleMetadataLayout.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct TupleMetadataLayout: MetadataLayoutType { 24 | var _kind: Int 25 | var numberOfElements: Int 26 | var labelsString: UnsafeMutablePointer 27 | var elementVector: Vector 28 | } 29 | 30 | struct TupleElementLayout { 31 | var type: Any.Type 32 | var offset: Int 33 | } 34 | -------------------------------------------------------------------------------- /Sources/Runtime/Pointers/Union.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | /// Helper for when binding to a c++ `union` 24 | protocol Union { 25 | associatedtype Raw 26 | var raw: Raw { get set } 27 | } 28 | 29 | extension Union { 30 | mutating func bind() -> UnsafeMutablePointer { 31 | return withUnsafePointer(to: &self) { pointer in 32 | return pointer.raw.assumingMemoryBound(to: T.self).mutable 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Sources/Runtime/Metadata/StructMetadata.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct StructMetadata: NominalMetadataType { 24 | 25 | var pointer: UnsafeMutablePointer 26 | 27 | mutating func toTypeInfo() -> TypeInfo { 28 | var info = TypeInfo(metadata: self) 29 | info.properties = properties() 30 | info.mangledName = mangledName() 31 | info.genericTypes = Array(genericArguments()) 32 | return info 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/ProtocolDescriptor.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct ProtocolDescriptor { 24 | var isaPointer: Int 25 | var mangledName: UnsafeMutablePointer 26 | var inheritedProtocolsList: Int 27 | var requiredInstanceMethods: Int 28 | var requiredClassMethods: Int 29 | var optionalInstanceMethods: Int 30 | var optionalClassMethods: Int 31 | var instanceProperties: Int 32 | var protocolDescriptorSize: Int32 33 | var flags: Int32 34 | } 35 | -------------------------------------------------------------------------------- /Sources/Runtime/Utilities/String+Extensions.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | extension Array where Element == String { 24 | 25 | static func from(pointer: UnsafePointer, n: Int) -> [String] { 26 | var pointer = pointer 27 | var result = [String]() 28 | 29 | for _ in 0.. Int { 37 | return MemoryLayout.size 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/TargetTypeGenericContextDescriptorHeader.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct TargetTypeGenericContextDescriptorHeader { 24 | var instantiationCache: Int32 25 | var defaultInstantiationPattern: Int32 26 | var base: TargetGenericContextDescriptorHeader 27 | } 28 | 29 | struct TargetGenericContextDescriptorHeader { 30 | var numberOfParams: UInt16 31 | var numberOfRequirements: UInt16 32 | var numberOfKeyArguments: UInt16 33 | var numberOfExtraArguments: UInt16 34 | } 35 | -------------------------------------------------------------------------------- /Sources/Runtime/Utilities/RetainCounts.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | public func retainCounts(of object: inout AnyObject) throws -> Int { 24 | return try withValuePointer(of: &object) { pointer in 25 | return Int(pointer.assumingMemoryBound(to: ClassHeader.self).pointee.strongRetainCounts) 26 | } 27 | } 28 | 29 | public func weakRetainCounts(of object: inout AnyObject) throws -> Int { 30 | return try withValuePointer(of: &object) { pointer in 31 | return Int(pointer.assumingMemoryBound(to: ClassHeader.self).pointee.weakRetainCounts) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/Runtime/Pointers/RelativeVectorPointer.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct RelativeVectorPointer { 24 | var offset: Offset 25 | mutating func vector(metadata: UnsafePointer, n: Int) -> UnsafeBufferPointer { 26 | return metadata.advanced(by: numericCast(offset)) 27 | .raw.assumingMemoryBound(to: Pointee.self) 28 | .buffer(n: n) 29 | } 30 | } 31 | 32 | extension RelativeVectorPointer: CustomStringConvertible { 33 | var description: String { 34 | return "\(offset)" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | .DS_Store 10 | 11 | ## Various settings 12 | *.pbxuser 13 | !default.pbxuser 14 | *.mode1v3 15 | !default.mode1v3 16 | *.mode2v3 17 | !default.mode2v3 18 | *.perspectivev3 19 | !default.perspectivev3 20 | xcuserdata/ 21 | *.xcodeproj 22 | 23 | ## Other 24 | *.moved-aside 25 | *.xccheckout 26 | *.xcscmblueprint 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | *.dSYM.zip 32 | *.dSYM 33 | 34 | ## Playgrounds 35 | timeline.xctimeline 36 | playground.xcworkspace 37 | 38 | # Swift Package Manager 39 | # 40 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 41 | # Packages/ 42 | # Package.pins 43 | .build/ 44 | RuntimeTests/TestProviders.swift 45 | 46 | # CocoaPods 47 | # 48 | # We recommend against adding the Pods directory to your .gitignore. However 49 | # you should judge for yourself, the pros and cons are mentioned at: 50 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 51 | # 52 | # Pods/ 53 | 54 | # Carthage 55 | # 56 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 57 | # Carthage/Checkouts 58 | 59 | Carthage/Build 60 | 61 | # fastlane 62 | # 63 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 64 | # screenshots whenever they are needed. 65 | # For more information about the recommended setup visit: 66 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 67 | 68 | fastlane/report.xml 69 | fastlane/Preview.html 70 | fastlane/screenshots 71 | fastlane/test_output 72 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/StructTypeDescriptor.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | typealias FieldTypeAccessor = @convention(c) (UnsafePointer) -> UnsafePointer 24 | 25 | struct StructTypeDescriptor: TypeDescriptor { 26 | var flags: ContextDescriptorFlags 27 | var parent: Int32 28 | var mangledName: RelativePointer 29 | var accessFunctionPtr: RelativePointer 30 | var fieldDescriptor: RelativePointer 31 | var numberOfFields: Int32 32 | var offsetToTheFieldOffsetVector: RelativeVectorPointer 33 | var genericContextHeader: TargetTypeGenericContextDescriptorHeader 34 | } 35 | -------------------------------------------------------------------------------- /Sources/Runtime/Models/FunctionInfo.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | public struct FunctionInfo { 24 | public var numberOfArguments: Int 25 | public var argumentTypes: [Any.Type] 26 | public var returnType: Any.Type 27 | public var `throws`: Bool 28 | } 29 | 30 | public func functionInfo(of function: Any) throws -> FunctionInfo { 31 | return try functionInfo(of: type(of: function)) 32 | } 33 | 34 | public func functionInfo(of type: Any.Type) throws -> FunctionInfo { 35 | let kind = Kind(type: type) 36 | guard kind == .function else { throw RuntimeError.couldNotGetTypeInfo(type: type, kind: kind) } 37 | return FunctionMetadata(type: type).info() 38 | } 39 | -------------------------------------------------------------------------------- /Sources/Runtime/Pointers/Vector.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct Vector { 24 | 25 | var element: Element 26 | 27 | mutating func vector(n: Int) -> UnsafeBufferPointer { 28 | return withUnsafePointer(to: &self) { 29 | $0.withMemoryRebound(to: Element.self, capacity: 1) { start in 30 | return start.buffer(n: n) 31 | } 32 | } 33 | } 34 | 35 | mutating func element(at i: Int) -> UnsafeMutablePointer { 36 | return withUnsafePointer(to: &self) { 37 | return $0.raw.assumingMemoryBound(to: Element.self).advanced(by: i).mutable 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/Runtime/Pointers/RelativePointer.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct RelativePointer { 24 | var offset: Offset 25 | 26 | mutating func pointee() -> Pointee { 27 | return advanced().pointee 28 | } 29 | 30 | mutating func advanced() -> UnsafeMutablePointer { 31 | let offset = self.offset 32 | return withUnsafePointer(to: &self) { p in 33 | return p.raw.advanced(by: numericCast(offset)) 34 | .assumingMemoryBound(to: Pointee.self) 35 | .mutable 36 | } 37 | } 38 | } 39 | 40 | extension RelativePointer: CustomStringConvertible { 41 | var description: String { 42 | return "\(offset)" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/TypeDescriptor.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | protocol TypeDescriptor { 24 | 25 | /// The offset type can differ between TypeDescriptors 26 | /// e.g. Struct are an Int32 and classes are an Int 27 | associatedtype FieldOffsetVectorOffsetType: FixedWidthInteger 28 | 29 | var flags: ContextDescriptorFlags { get set } 30 | var mangledName: RelativePointer { get set } 31 | var fieldDescriptor: RelativePointer { get set } 32 | var numberOfFields: Int32 { get set } 33 | var offsetToTheFieldOffsetVector: RelativeVectorPointer { get set } 34 | var genericContextHeader: TargetTypeGenericContextDescriptorHeader { get set } 35 | } 36 | 37 | typealias ContextDescriptorFlags = Int32 38 | -------------------------------------------------------------------------------- /Sources/Runtime/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_library(Runtime 3 | Factory/DefaultValue.swift 4 | Factory/Factory.swift 5 | Layouts/ClassHeader.swift 6 | Layouts/ClassMetadataLayout.swift 7 | Layouts/ClassTypeDescriptor.swift 8 | Layouts/EnumMetadataLayout.swift 9 | Layouts/EnumTypeDescriptor.swift 10 | Layouts/ExistentialContainter.swift 11 | Layouts/FieldDescriptor.swift 12 | Layouts/FunctionMetadataLayout.swift 13 | Layouts/MetadataLayoutType.swift 14 | Layouts/ProtocolDescriptor.swift 15 | Layouts/ProtocolMetadataLayout.swift 16 | Layouts/ProtocolTypeContainer.swift 17 | Layouts/StructMetadataLayout.swift 18 | Layouts/StructTypeDescriptor.swift 19 | Layouts/TargetTypeGenericContextDescriptorHeader.swift 20 | Layouts/TupleMetadataLayout.swift 21 | Layouts/TypeDescriptor.swift 22 | Layouts/ValueWitnessTable.swift 23 | Metadata/ClassMetadata.swift 24 | Metadata/EnumMetadata.swift 25 | Metadata/FuntionMetadata.swift 26 | Metadata/Metadata.swift 27 | Metadata/MetadataType.swift 28 | Metadata/NominalMetadataType.swift 29 | Metadata/ProtocolMetadata.swift 30 | Metadata/StructMetadata.swift 31 | Metadata/TupleMetadata.swift 32 | Models/Case.swift 33 | Models/Errors.swift 34 | Models/FunctionInfo.swift 35 | Models/Kind.swift 36 | Models/PropertyInfo.swift 37 | Models/TypeInfo.swift 38 | Models/TypeInfoConvertible.swift 39 | Pointers/Pointers.swift 40 | Pointers/RelativePointer.swift 41 | Pointers/RelativeVectorPointer.swift 42 | Pointers/Union.swift 43 | Pointers/Vector.swift 44 | Utilities/GettersSetters.swift 45 | Utilities/Pointer+Extensions.swift 46 | Utilities/RetainCounts.swift 47 | Utilities/String+Extensions.swift) 48 | 49 | target_compile_options(Runtime PRIVATE 50 | "SHELL:$<$:-Xcc -D_CRT_SECURE_NO_WARNINGS>") 51 | 52 | target_include_directories(Runtime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../CRuntime) 53 | 54 | set_target_properties(Runtime PROPERTIES 55 | INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) 56 | 57 | swift_install(TARGETS Runtime 58 | EXPORT Runtime) -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/ValueWitnessTable.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct ValueWitnessTable { 24 | var initializeBufferWithCopyOfBuffer: UnsafeRawPointer 25 | var destroy: UnsafeRawPointer 26 | var initializeWithCopy: UnsafeRawPointer 27 | var assignWithCopy: UnsafeRawPointer 28 | var initializeWithTake: UnsafeRawPointer 29 | var assignWithTake: UnsafeRawPointer 30 | var getEnumTagSinglePayload: UnsafeRawPointer 31 | var storeEnumTagSinglePayload: UnsafeRawPointer 32 | var size: Int 33 | var stride: Int 34 | var flags: Int 35 | } 36 | 37 | struct ValueWitnessFlags { 38 | static let alignmentMask = 0x0000FFFF 39 | static let isNonPOD = 0x00010000 40 | static let isNonInline = 0x00020000 41 | static let hasExtraInhabitants = 0x00040000 42 | static let hasSpareBits = 0x00080000 43 | static let isNonBitwiseTakable = 0x00100000 44 | static let hasEnumWitnesses = 0x00200000 45 | } 46 | -------------------------------------------------------------------------------- /Tests/RuntimeTests/ValueWitnessTableTests.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import XCTest 24 | @testable import Runtime 25 | 26 | class ValueWitnessTableTests: XCTestCase { 27 | 28 | static var allTests: [(String, (ValueWitnessTableTests) -> () throws -> Void)] { 29 | return [ 30 | ("testSize", testSize), 31 | ("testAlignment", testAlignment), 32 | ("testStride", testStride) 33 | ] 34 | } 35 | 36 | func testSize() throws { 37 | let info = try typeInfo(of: Person.self) 38 | XCTAssert(info.size == MemoryLayout.size) 39 | } 40 | 41 | func testAlignment() throws { 42 | let info = try typeInfo(of: Person.self) 43 | XCTAssert(info.alignment == MemoryLayout.alignment) 44 | } 45 | 46 | func testStride() throws { 47 | let info = try typeInfo(of: Person.self) 48 | XCTAssert(info.stride == MemoryLayout.stride) 49 | } 50 | 51 | } 52 | 53 | fileprivate struct Person { 54 | let firstname: String 55 | let lastname: String 56 | let age: Int 57 | } 58 | -------------------------------------------------------------------------------- /Sources/Runtime/Utilities/GettersSetters.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | protocol Getters {} 24 | extension Getters { 25 | static func get(from pointer: UnsafeRawPointer) -> Any { 26 | return pointer.assumingMemoryBound(to: Self.self).pointee 27 | } 28 | } 29 | 30 | func getters(type: Any.Type) -> Getters.Type { 31 | let container = ProtocolTypeContainer(type: type, witnessTable: 0) 32 | return unsafeBitCast(container, to: Getters.Type.self) 33 | } 34 | 35 | protocol Setters {} 36 | extension Setters { 37 | static func set(value: Any, pointer: UnsafeMutableRawPointer, initialize: Bool = false) { 38 | if let value = value as? Self { 39 | let boundPointer = pointer.assumingMemoryBound(to: self); 40 | if initialize { 41 | boundPointer.initialize(to: value) 42 | } else { 43 | boundPointer.pointee = value 44 | } 45 | } 46 | } 47 | } 48 | 49 | func setters(type: Any.Type) -> Setters.Type { 50 | let container = ProtocolTypeContainer(type: type, witnessTable: 0) 51 | return unsafeBitCast(container, to: Setters.Type.self) 52 | } 53 | -------------------------------------------------------------------------------- /Sources/Runtime/Metadata/Metadata.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | func metadataPointer(type: Any.Type) -> UnsafeMutablePointer { 24 | return unsafeBitCast(type, to: UnsafeMutablePointer.self) 25 | } 26 | 27 | func metadata(of type: Any.Type) throws -> MetadataInfo { 28 | 29 | let kind = Kind(type: type) 30 | 31 | switch kind { 32 | case .struct: 33 | return StructMetadata(type: type) 34 | case .class: 35 | return ClassMetadata(type: type) 36 | case .existential: 37 | return ProtocolMetadata(type: type) 38 | case .tuple: 39 | return TupleMetadata(type: type) 40 | case .enum: 41 | return EnumMetadata(type: type) 42 | default: 43 | throw RuntimeError.couldNotGetTypeInfo(type: type, kind: kind) 44 | } 45 | } 46 | 47 | func swiftObject() -> Any.Type { 48 | class Temp {} 49 | let md = ClassMetadata(type: Temp.self) 50 | return md.pointer.pointee.superClass 51 | } 52 | 53 | func classIsSwiftMask() -> Int { 54 | #if canImport(Darwin) 55 | if #available(macOS 10.14.4, iOS 12.2, tvOS 12.2, watchOS 5.2, *) { 56 | return 2 57 | } 58 | #endif 59 | return 1 60 | } 61 | -------------------------------------------------------------------------------- /Sources/Runtime/Metadata/FuntionMetadata.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct FunctionMetadata: MetadataType { 24 | 25 | var pointer: UnsafeMutablePointer 26 | 27 | func info() -> FunctionInfo { 28 | let (numberOfArguments, argumentTypes, returnType) = argumentInfo() 29 | return FunctionInfo(numberOfArguments: numberOfArguments, 30 | argumentTypes: argumentTypes, 31 | returnType: returnType, 32 | throws: `throws`()) 33 | } 34 | 35 | private func argumentInfo() -> (Int, [Any.Type], Any.Type) { 36 | let n = numberArguments() 37 | let argTypeBuffer = pointer.pointee.argumentVector.vector(n: n + 1) 38 | 39 | let resultType = argTypeBuffer[0] 40 | let argTypes = Array(argTypeBuffer.dropFirst()) 41 | 42 | return (n, argTypes, resultType) 43 | } 44 | 45 | private func numberArguments() -> Int { 46 | return pointer.pointee.flags & 0x0000FFFF 47 | } 48 | 49 | private func `throws`() -> Bool { 50 | return pointer.pointee.flags & 0x01000000 != 0 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Sources/Runtime/Utilities/Pointer+Extensions.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | extension UnsafePointer { 24 | 25 | var raw: UnsafeRawPointer { 26 | return UnsafeRawPointer(self) 27 | } 28 | 29 | var mutable: UnsafeMutablePointer { 30 | return UnsafeMutablePointer(mutating: self) 31 | } 32 | 33 | func buffer(n: Int) -> UnsafeBufferPointer { 34 | return UnsafeBufferPointer(start: self, count: n) 35 | } 36 | } 37 | 38 | extension UnsafePointer where Pointee: Equatable { 39 | func advance(to value: Pointee) -> UnsafePointer { 40 | var pointer = self 41 | while pointer.pointee != value { 42 | pointer = pointer.advanced(by: 1) 43 | } 44 | return pointer 45 | } 46 | } 47 | 48 | extension UnsafeMutablePointer { 49 | 50 | var raw: UnsafeMutableRawPointer { 51 | return UnsafeMutableRawPointer(self) 52 | } 53 | 54 | func buffer(n: Int) -> UnsafeMutableBufferPointer { 55 | return UnsafeMutableBufferPointer(start: self, count: n) 56 | } 57 | 58 | func advanced(by n: Int, wordSize: Int) -> UnsafeMutableRawPointer { 59 | return self.raw.advanced(by: n * wordSize) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Sources/Runtime/Factory/DefaultValue.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #if canImport(Foundation) 24 | import Foundation 25 | #endif 26 | 27 | public protocol DefaultConstructor { 28 | init() 29 | } 30 | 31 | extension Int: DefaultConstructor {} 32 | extension Int8: DefaultConstructor {} 33 | extension Int16: DefaultConstructor {} 34 | extension Int32: DefaultConstructor {} 35 | extension Int64: DefaultConstructor {} 36 | extension UInt: DefaultConstructor {} 37 | extension UInt8: DefaultConstructor {} 38 | extension UInt16: DefaultConstructor {} 39 | extension UInt32: DefaultConstructor {} 40 | extension UInt64: DefaultConstructor {} 41 | extension String: DefaultConstructor {} 42 | 43 | extension Bool: DefaultConstructor {} 44 | extension Double: DefaultConstructor {} 45 | extension Float: DefaultConstructor {} 46 | 47 | #if canImport(Foundation) 48 | extension Decimal: DefaultConstructor {} 49 | extension Date: DefaultConstructor {} 50 | extension UUID: DefaultConstructor {} 51 | extension Data: DefaultConstructor {} 52 | #endif 53 | 54 | extension Array: DefaultConstructor {} 55 | extension Dictionary: DefaultConstructor {} 56 | extension Set: DefaultConstructor {} 57 | 58 | extension Character: DefaultConstructor { 59 | public init() { 60 | self = " " 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/ClassTypeDescriptor.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct ClassTypeDescriptor: TypeDescriptor { 24 | var flags: ContextDescriptorFlags 25 | var parent: Int32 26 | var mangledName: RelativePointer 27 | var fieldTypesAccessor: RelativePointer 28 | var fieldDescriptor: RelativePointer 29 | var superClass: RelativePointer 30 | var negativeSizeAndBoundsUnion: NegativeSizeAndBoundsUnion 31 | var metadataPositiveSizeInWords: Int32 32 | var numImmediateMembers: Int32 33 | var numberOfFields: Int32 34 | var offsetToTheFieldOffsetVector: RelativeVectorPointer 35 | var genericContextHeader: TargetTypeGenericContextDescriptorHeader 36 | 37 | struct NegativeSizeAndBoundsUnion: Union { 38 | var raw: Int32 39 | 40 | var metadataNegativeSizeInWords: Int32 { 41 | return raw 42 | } 43 | 44 | mutating func resilientMetadataBounds() -> UnsafeMutablePointer> { 45 | return bind() 46 | } 47 | } 48 | } 49 | 50 | struct TargetStoredClassMetadataBounds { 51 | var immediateMembersOffset: Int 52 | var bounds: TargetMetadataBounds 53 | } 54 | 55 | struct TargetMetadataBounds { 56 | var negativeSizeWords: UInt32 57 | var positiveSizeWords: UInt32 58 | } 59 | -------------------------------------------------------------------------------- /Sources/Runtime/Metadata/TupleMetadata.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct TupleMetadata: MetadataType, TypeInfoConvertible { 24 | 25 | var pointer: UnsafeMutablePointer 26 | 27 | func numberOfElements() -> Int { 28 | return pointer.pointee.numberOfElements 29 | } 30 | 31 | func labels() -> [String] { 32 | guard Int(bitPattern: pointer.pointee.labelsString) != 0 else { return (0.. UnsafeBufferPointer { 39 | return pointer.pointee.elementVector.vector(n: numberOfElements()) 40 | } 41 | 42 | func properies() -> [PropertyInfo] { 43 | let names = labels() 44 | let el = elements() 45 | let num = numberOfElements() 46 | var properties = [PropertyInfo]() 47 | for i in 0.. TypeInfo { 54 | var info = TypeInfo(metadata: self) 55 | info.properties = properies() 56 | return info 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | 9 | jobs: 10 | linux: 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | image: 17 | - swift:5.1-xenial 18 | - swift:5.1-bionic 19 | - swift:5.2-xenial 20 | - swift:5.2-bionic 21 | - swift:5.2-focal 22 | - swift:5.2-centos8 23 | - swift:5.2-amazonlinux2 24 | - swift:5.3-xenial 25 | - swift:5.3-bionic 26 | - swift:5.3-focal 27 | - swift:5.3-centos8 28 | - swift:5.3-amazonlinux2 29 | - swift:5.4-xenial 30 | - swift:5.4-bionic 31 | - swift:5.4-focal 32 | - swift:5.4-centos8 33 | - swift:5.4-amazonlinux2 34 | - swiftlang/swift:nightly-5.4-xenial 35 | - swiftlang/swift:nightly-5.4-bionic 36 | - swiftlang/swift:nightly-5.4-focal 37 | - swiftlang/swift:nightly-5.4-centos8 38 | - swiftlang/swift:nightly-5.4-amazonlinux2 39 | - swiftlang/swift:nightly-5.5-xenial 40 | - swiftlang/swift:nightly-5.5-bionic 41 | - swiftlang/swift:nightly-5.5-focal 42 | - swiftlang/swift:nightly-5.5-centos8 43 | - swiftlang/swift:nightly-5.5-amazonlinux2 44 | configuration: 45 | - debug 46 | - release 47 | 48 | container: ${{ matrix.image }} 49 | 50 | steps: 51 | - name: Checkout code 52 | uses: actions/checkout@v2 53 | 54 | - name: Run tests (debug) 55 | if: matrix.configuration == 'debug' 56 | run: swift test 57 | 58 | # running tests in release configuration to ensure everything works as expected with compiler optimizations 59 | - name: Run tests (release) 60 | if: matrix.configuration == 'release' 61 | run: swift test -c release -Xswiftc -enable-testing -Xswiftc -DDEBUG 62 | macos: 63 | 64 | runs-on: macos-latest 65 | 66 | strategy: 67 | matrix: 68 | configuration: 69 | - debug 70 | - release 71 | 72 | steps: 73 | - name: Select latest available Xcode 74 | uses: maxim-lobanov/setup-xcode@v1.2.1 75 | with: { 'xcode-version': 'latest' } 76 | 77 | - name: Checkout code 78 | uses: actions/checkout@v2 79 | 80 | - name: Run tests (debug) 81 | if: matrix.configuration == 'debug' 82 | run: swift test 83 | 84 | # running tests in release configuration to ensure everything works as expected with compiler optimizations 85 | - name: Run tests (release) 86 | if: matrix.configuration == 'release' 87 | run: swift test -c release -Xswiftc -enable-testing -Xswiftc -DDEBUG -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/ClassMetadataLayout.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | // Note: With the release of swift 5.4 the ClassMetadataLayout changed for platforms without Objective-C interoperability 24 | // see: https://github.com/apple/swift/commit/38fc849a1fc8ea703de2fd1f280b43c682b70257#diff-22fb9f1513d9c05f34d493826b4553bba65a4336a41ae4413678feec549db3a5 25 | // related issue: https://github.com/wickwirew/Runtime/issues/92 26 | 27 | // Swift class or objc class 28 | struct AnyClassMetadataLayout { 29 | var _kind: Int // isaPointer for classes 30 | var superClass: Any.Type 31 | 32 | // see comment above 33 | #if !swift(>=5.4) || canImport(ObjectiveC) 34 | var objCRuntimeReserve: (Int, Int) 35 | var rodataPointer: Int 36 | #endif 37 | 38 | var isSwiftClass: Bool { 39 | // see comment above 40 | #if !swift(>=5.4) || canImport(ObjectiveC) 41 | return (rodataPointer & classIsSwiftMask()) != 0 42 | #else 43 | return true 44 | #endif 45 | } 46 | } 47 | 48 | struct ClassMetadataLayout: NominalMetadataLayoutType { 49 | var _kind: Int // isaPointer for classes 50 | var superClass: Any.Type 51 | 52 | // see comment above 53 | #if !swift(>=5.4) || canImport(ObjectiveC) 54 | var objCRuntimeReserve: (Int, Int) 55 | var rodataPointer: Int 56 | #endif 57 | 58 | var classFlags: Int32 59 | var instanceAddressPoint: UInt32 60 | var instanceSize: UInt32 61 | var instanceAlignmentMask: UInt16 62 | var reserved: UInt16 63 | var classSize: UInt32 64 | var classAddressPoint: UInt32 65 | var typeDescriptor: UnsafeMutablePointer 66 | var iVarDestroyer: UnsafeRawPointer 67 | } 68 | -------------------------------------------------------------------------------- /Sources/Runtime/Metadata/MetadataType.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | protocol MetadataInfo { 24 | 25 | var kind: Kind { get } 26 | var size: Int { get } 27 | var alignment: Int { get } 28 | var stride: Int { get } 29 | 30 | init(type: Any.Type) 31 | } 32 | 33 | protocol MetadataType: MetadataInfo, TypeInfoConvertible { 34 | 35 | associatedtype Layout: MetadataLayoutType 36 | 37 | var pointer: UnsafeMutablePointer { get set } 38 | 39 | init(pointer: UnsafeMutablePointer) 40 | } 41 | 42 | extension MetadataType { 43 | 44 | init(type: Any.Type) { 45 | self = Self(pointer: unsafeBitCast(type, to: UnsafeMutablePointer.self)) 46 | } 47 | 48 | var type: Any.Type { 49 | return unsafeBitCast(pointer, to: Any.Type.self) 50 | } 51 | 52 | var kind: Kind { 53 | return Kind(flag: pointer.pointee._kind) 54 | } 55 | 56 | var size: Int { 57 | return valueWitnessTable.pointee.size 58 | } 59 | 60 | var alignment: Int { 61 | return (valueWitnessTable.pointee.flags & ValueWitnessFlags.alignmentMask) + 1 62 | } 63 | 64 | var stride: Int { 65 | return valueWitnessTable.pointee.stride 66 | } 67 | 68 | /// The ValueWitnessTable for the type. 69 | /// A pointer to the table is located one pointer sized word behind the metadata pointer. 70 | var valueWitnessTable: UnsafeMutablePointer { 71 | return pointer 72 | .raw 73 | .advanced(by: -MemoryLayout.size) 74 | .assumingMemoryBound(to: UnsafeMutablePointer.self) 75 | .pointee 76 | } 77 | 78 | mutating func toTypeInfo() -> TypeInfo { 79 | return TypeInfo(metadata: self) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Sources/Runtime/Metadata/EnumMetadata.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct EnumMetadata: NominalMetadataType { 24 | 25 | var pointer: UnsafeMutablePointer 26 | 27 | var numberOfPayloadCases: UInt32 { 28 | return pointer.pointee.typeDescriptor.pointee.numPayloadCasesAndPayloadSizeOffset & 0x00FFFFFF 29 | } 30 | 31 | var numberOfCases: UInt32 { 32 | return pointer.pointee.typeDescriptor.pointee.numEmptyCases + numberOfPayloadCases 33 | } 34 | 35 | mutating func cases() -> [Case] { 36 | guard pointer.pointee.typeDescriptor.pointee.fieldDescriptor.offset != 0 else { 37 | return [] 38 | } 39 | 40 | let fieldDescriptor = pointer.pointee 41 | .typeDescriptor.pointee 42 | .fieldDescriptor.advanced() 43 | 44 | let genericVector = genericArgumentVector() 45 | 46 | return (0.. TypeInfo { 65 | var info = TypeInfo(metadata: self) 66 | info.mangledName = mangledName() 67 | info.cases = cases() 68 | info.genericTypes = Array(genericArguments()) 69 | info.numberOfEnumCases = Int(numberOfCases) 70 | info.numberOfPayloadEnumCases = Int(numberOfPayloadCases) 71 | return info 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Sources/Runtime/Models/PropertyInfo.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | public struct PropertyInfo { 24 | 25 | public let name: String 26 | public let type: Any.Type 27 | public let isVar: Bool 28 | public let offset: Int 29 | public let ownerType: Any.Type 30 | 31 | public func set(value: Any, on object: inout TObject) throws { 32 | try withValuePointer(of: &object) { pointer in 33 | try set(value: value, pointer: pointer) 34 | } 35 | } 36 | 37 | public func set(value: Any, on object: inout Any) throws { 38 | try withValuePointer(of: &object) { pointer in 39 | try set(value: value, pointer: pointer) 40 | } 41 | } 42 | 43 | private func set(value: Any, pointer: UnsafeMutableRawPointer) throws { 44 | let valuePointer = pointer.advanced(by: offset) 45 | let sets = setters(type: type) 46 | sets.set(value: value, pointer: valuePointer) 47 | } 48 | 49 | public func get(from object: Any) throws -> TValue { 50 | if let value = try get(from: object) as? TValue { 51 | return value 52 | } 53 | 54 | throw RuntimeError.errorGettingValue(name: name, type: type) 55 | } 56 | 57 | public func get(from object: Any) throws -> Any { 58 | var object = object 59 | return try withValuePointer(of: &object) { pointer in 60 | let valuePointer = pointer.advanced(by: offset) 61 | let gets = getters(type: type) 62 | return gets.get(from: valuePointer) 63 | } 64 | } 65 | } 66 | 67 | extension PropertyInfo: Equatable { 68 | public static func == (lhs: PropertyInfo, rhs: PropertyInfo) -> Bool { 69 | return lhs.name == rhs.name 70 | && lhs.type == rhs.type 71 | && lhs.isVar == rhs.isVar 72 | && lhs.offset == rhs.offset 73 | && lhs.ownerType == rhs.ownerType 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Sources/Runtime/Models/TypeInfo.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | public struct TypeInfo { 24 | 25 | public var kind: Kind = .class 26 | public var name: String = "" 27 | public var type: Any.Type = Any.self 28 | public var mangledName: String = "" 29 | public var properties: [PropertyInfo] = [] 30 | public var inheritance: [Any.Type] = [] 31 | public var size: Int = 0 32 | public var alignment: Int = 0 33 | public var stride: Int = 0 34 | public var cases: [Case] = [] 35 | public var numberOfEnumCases: Int = 0 36 | public var numberOfPayloadEnumCases: Int = 0 37 | public var genericTypes: [Any.Type] = [] 38 | 39 | init(metadata: Metadata) { 40 | kind = metadata.kind 41 | size = metadata.size 42 | alignment = metadata.alignment 43 | stride = metadata.stride 44 | type = metadata.type 45 | name = String(describing: metadata.type) 46 | } 47 | 48 | public var superClass: Any.Type? { 49 | return inheritance.first 50 | } 51 | 52 | public func property(named: String) throws -> PropertyInfo { 53 | if let prop = properties.first(where: { $0.name == named }) { 54 | return prop 55 | } 56 | 57 | throw RuntimeError.noPropertyNamed(name: named) 58 | } 59 | } 60 | 61 | public func typeInfo(of type: Any.Type) throws -> TypeInfo { 62 | let kind = Kind(type: type) 63 | 64 | var typeInfoConvertible: TypeInfoConvertible 65 | 66 | switch kind { 67 | case .struct: 68 | typeInfoConvertible = StructMetadata(type: type) 69 | case .class: 70 | typeInfoConvertible = ClassMetadata(type: type) 71 | case .existential: 72 | typeInfoConvertible = ProtocolMetadata(type: type) 73 | case .tuple: 74 | typeInfoConvertible = TupleMetadata(type: type) 75 | case .enum, .optional: 76 | typeInfoConvertible = EnumMetadata(type: type) 77 | default: 78 | throw RuntimeError.couldNotGetTypeInfo(type: type, kind: kind) 79 | } 80 | 81 | return typeInfoConvertible.toTypeInfo() 82 | } 83 | -------------------------------------------------------------------------------- /Sources/Runtime/Pointers/Pointers.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | func withValuePointer( 24 | of value: inout Value, 25 | _ body: (UnsafeMutableRawPointer) throws -> Result) throws -> Result { 26 | 27 | let kind = Kind(type: Value.self) 28 | 29 | switch kind { 30 | case .struct: 31 | return try withUnsafePointer(to: &value) { try body($0.mutable.raw) } 32 | case .class: 33 | return try withClassValuePointer(of: &value, body) 34 | case .existential: 35 | return try withExistentialValuePointer(of: &value, body) 36 | default: 37 | throw RuntimeError.couldNotGetPointer(type: Value.self, value: value) 38 | } 39 | } 40 | 41 | func withClassValuePointer( 42 | of value: inout Value, 43 | _ body: (UnsafeMutableRawPointer) throws -> Result) throws -> Result { 44 | return try withUnsafePointer(to: &value) { 45 | return try $0.withMemoryRebound(to: UnsafeMutableRawPointer.self, capacity: 1) { 46 | try body($0.pointee) 47 | } 48 | } 49 | } 50 | 51 | func withExistentialValuePointer( 52 | of value: inout Value, 53 | _ body: (UnsafeMutableRawPointer) throws -> Result) throws -> Result { 54 | return try withUnsafePointer(to: &value) { ptr in 55 | try ptr.withMemoryRebound(to: ExistentialContainer.self, capacity: 1) { 56 | let container = $0.pointee 57 | let info = try metadata(of: container.type) 58 | if info.kind == .class || info.size > ExistentialContainerBuffer.size() { 59 | return try ptr.withMemoryRebound(to: UnsafeMutableRawPointer.self, capacity: 1) { 60 | let base = $0.pointee 61 | if info.kind == .struct { 62 | return try body(base.advanced(by: existentialHeaderSize)) 63 | } else { 64 | return try body(base) 65 | } 66 | } 67 | } else { 68 | return try body($0.mutable.raw) 69 | } 70 | } 71 | } 72 | } 73 | 74 | var existentialHeaderSize: Int { 75 | if is64Bit { 76 | return 16 77 | } else { 78 | return 8 79 | } 80 | } 81 | 82 | var is64Bit: Bool { 83 | return MemoryLayout.size == 8 84 | } 85 | -------------------------------------------------------------------------------- /Sources/Runtime/Layouts/FieldDescriptor.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #if canImport(CRuntime) 24 | import CRuntime 25 | #endif 26 | 27 | /// https://github.com/apple/swift/blob/f2c42509628bed66bf5b8ee02fae778a2ba747a1/include/swift/Reflection/Records.h#L160 28 | struct FieldDescriptor { 29 | 30 | var mangledTypeNameOffset: Int32 31 | var superClassOffset: Int32 32 | var _kind: UInt16 33 | var fieldRecordSize: Int16 34 | var numFields: Int32 35 | var fields: Vector 36 | 37 | var kind: FieldDescriptorKind { 38 | return FieldDescriptorKind(rawValue: _kind)! 39 | } 40 | } 41 | 42 | struct FieldRecord { 43 | 44 | var fieldRecordFlags: Int32 45 | var _mangledTypeName: RelativePointer 46 | var _fieldName: RelativePointer 47 | 48 | var isVar: Bool { 49 | return (fieldRecordFlags & 0x2) == 0x2 50 | } 51 | 52 | mutating func fieldName() -> String { 53 | return String(cString: _fieldName.advanced()) 54 | } 55 | 56 | mutating func type(genericContext: UnsafeRawPointer?, 57 | genericArguments: UnsafeRawPointer?) -> Any.Type { 58 | let typeName = _mangledTypeName.advanced() 59 | let metadataPtr = swift_getTypeByMangledNameInContext( 60 | typeName, 61 | getSymbolicMangledNameLength(typeName), 62 | genericContext, 63 | genericArguments?.assumingMemoryBound(to: Optional.self) 64 | )! 65 | 66 | return unsafeBitCast(metadataPtr, to: Any.Type.self) 67 | } 68 | 69 | func getSymbolicMangledNameLength(_ base: UnsafeRawPointer) -> Int32 { 70 | var end = base 71 | while let current = Optional(end.load(as: UInt8.self)), current != 0 { 72 | end += 1 73 | if current >= 0x1 && current <= 0x17 { 74 | end += 4 75 | } else if current >= 0x18 && current <= 0x1F { 76 | end += MemoryLayout.size 77 | } 78 | } 79 | 80 | return Int32(end - base) 81 | } 82 | } 83 | 84 | enum FieldDescriptorKind: UInt16 { 85 | case `struct` 86 | case `class` 87 | case `enum` 88 | case multiPayloadEnum 89 | case `protocol` 90 | case classProtocol 91 | case objcProtocol 92 | case objcClass 93 | } 94 | -------------------------------------------------------------------------------- /Sources/Runtime/Models/Kind.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | public enum Kind { 24 | case `struct` 25 | case `enum` 26 | case optional 27 | case opaque 28 | case tuple 29 | case function 30 | case existential 31 | case metatype 32 | case objCClassWrapper 33 | case existentialMetatype 34 | case foreignClass 35 | case heapLocalVariable 36 | case heapGenericLocalVariable 37 | case errorObject 38 | case `class` 39 | init(flag: Int) { 40 | switch flag { 41 | case 1: self = .struct 42 | case (0 | Flags.kindIsNonHeap): self = .struct 43 | case 2: self = .enum 44 | case (1 | Flags.kindIsNonHeap): self = .enum 45 | case 3: self = .optional 46 | case (2 | Flags.kindIsNonHeap): self = .optional 47 | case 8: self = .opaque 48 | case (3 | Flags.kindIsNonHeap): self = .foreignClass 49 | case 9: self = .tuple 50 | case (0 | Flags.kindIsRuntimePrivate | Flags.kindIsNonHeap): self = .opaque 51 | case 10: self = .function 52 | case (1 | Flags.kindIsRuntimePrivate | Flags.kindIsNonHeap): self = .tuple 53 | case 12: self = .existential 54 | case (2 | Flags.kindIsRuntimePrivate | Flags.kindIsNonHeap): self = .function 55 | case 13: self = .metatype 56 | case (3 | Flags.kindIsRuntimePrivate | Flags.kindIsNonHeap): self = .existential 57 | case 14: self = .objCClassWrapper 58 | case (4 | Flags.kindIsRuntimePrivate | Flags.kindIsNonHeap): self = .metatype 59 | case 15: self = .existentialMetatype 60 | case (5 | Flags.kindIsRuntimePrivate | Flags.kindIsNonHeap): self = .objCClassWrapper 61 | case 16: self = .foreignClass 62 | case (6 | Flags.kindIsRuntimePrivate | Flags.kindIsNonHeap): self = .existentialMetatype 63 | case 64: self = .heapLocalVariable 64 | case (0 | Flags.kindIsNonType): self = .heapLocalVariable 65 | case 65: self = .heapGenericLocalVariable 66 | case (0 | Flags.kindIsNonType | Flags.kindIsRuntimePrivate): self = .heapGenericLocalVariable 67 | case 128: self = .errorObject 68 | case (1 | Flags.kindIsNonType | Flags.kindIsRuntimePrivate): self = .errorObject 69 | default: self = .class 70 | } 71 | } 72 | 73 | init(type: Any.Type) { 74 | let pointer = metadataPointer(type: type) 75 | self.init(flag: pointer.pointee) 76 | } 77 | 78 | struct Flags { 79 | static let kindIsNonHeap = 0x200 80 | static let kindIsRuntimePrivate = 0x100 81 | static let kindIsNonType = 0x400 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Scripts/TestCaseGen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | import sys 4 | import string 5 | import glob 6 | 7 | 8 | def build_provider_file(): 9 | return 10 | 11 | 12 | def build_provider_extension(class_name, functions): 13 | if len(functions) == 0: 14 | return "" 15 | 16 | map = get_function_map(functions) 17 | return """ 18 | extension """ + class_name + """ { 19 | var allTests : [(String, () throws -> Void)] { 20 | return [""" + map + """ 21 | ] 22 | } 23 | } 24 | """ 25 | 26 | 27 | def get_function_map(functions): 28 | result = "" 29 | 30 | for func in functions: 31 | result += "\n (\"" + func + "\", " + func + ")," 32 | 33 | return result 34 | 35 | 36 | def get_function_name(words): 37 | for word in words: 38 | if word != "public" and word != "func" and word != "static" \ 39 | and word != "private" and word != "open" and word != "fileprivate": 40 | return word.replace("()", "") 41 | 42 | return "" 43 | 44 | 45 | def is_test_function(words): 46 | if not words.__contains__("func"): 47 | return False 48 | 49 | function_name = str(get_function_name(words)) 50 | 51 | return function_name.__contains__("test") 52 | 53 | 54 | def is_class_declaration(words): 55 | return words.__contains__("class") and words.__contains__("XCTestCase") 56 | 57 | 58 | def get_class_name(words): 59 | for word in words: 60 | if word != "public" and word != "class" and word != "static" \ 61 | and word != "private" and word != "open" and word != "fileprivate": 62 | return word.replace(":", "") 63 | 64 | return "" 65 | 66 | 67 | def get_words(line): 68 | line_str = str(line).strip() 69 | words = line_str.split(' ', 10) 70 | 71 | while '' in words: 72 | words.remove('') 73 | 74 | return words 75 | 76 | 77 | def generate_providers(): 78 | test_path = "../RuntimeTests/*" 79 | output_file = "../RuntimeTests/TestProviders.swift" 80 | linux_main = "../RuntimeTests/LinuxMain.swift" 81 | 82 | extensions = [] 83 | class_names = [] 84 | 85 | files = glob.glob(test_path) 86 | 87 | for fle in files: 88 | with open(fle) as f: 89 | class_name_found = False 90 | class_name = "" 91 | functions = [] 92 | 93 | if fle.title().lower().__contains__(".swift"): 94 | for line in f.readlines(): 95 | words = get_words(line) 96 | 97 | if is_class_declaration(words) and not class_name_found: 98 | class_name = get_class_name(words) 99 | class_name_found = True 100 | class_names.append(class_name) 101 | elif is_test_function(words): 102 | functions.append(get_function_name(words)) 103 | 104 | extensions.append(build_provider_extension(class_name, functions)) 105 | 106 | with open(output_file, "w") as f: 107 | f.write("// This file is generated. Please do not add to source control.\n") 108 | f.write("@testable import Runtime\n") 109 | f.write("import XCTest\n\n") 110 | 111 | for ext in extensions: 112 | f.write(ext) 113 | continue 114 | 115 | with open(linux_main, "w") as f: 116 | f.write("// This file is generated. Please do not add to source control.\n") 117 | f.write("@testable import Runtime\n") 118 | f.write("import XCTest\n\n") 119 | 120 | f.write("XCTMain([") 121 | for c in class_names: 122 | f.write(" \n testCase(" + c + ".allTests),") 123 | continue 124 | f.write("\n])") 125 | 126 | 127 | if __name__ == '__main__': 128 | generate_providers() 129 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Runtime](https://github.com/wickwirew/Runtime/blob/master/Resources/Runtime.png) 2 | 3 | 4 | ![Swift 5.0](https://img.shields.io/badge/Swift-5.0-green.svg) 5 | [![CocoaPods compatible](https://img.shields.io/cocoapods/v/Runtime.svg)](#cocoapods) 6 | [![License](http://img.shields.io/:license-mit-blue.svg)](http://doge.mit-license.org) 7 | 8 | Runtime is a Swift library to give you more runtime abilities, including getting type metadata, setting properties via reflection, and type construction for native swift objects. 9 | 10 | ## TypeInfo 11 | `TypeInfo` exposes metadata about native Swift structs, protocols, classes, tuples and enums. It captures the properties, generic types, inheritance levels, and more. 12 | ### Example 13 | Lets say you have a User struct: 14 | ```swift 15 | struct User { 16 | let id: Int 17 | let username: String 18 | let email: String 19 | } 20 | ``` 21 | To get the `TypeInfo` of `User`, all that you have to do is: 22 | ```swift 23 | let info = try typeInfo(of: User.self) 24 | ``` 25 | 26 | ## Property Info 27 | Within the `TypeInfo` object, it contains a list of `PropertyInfo` which represents all properties for the type. `PropertyInfo` exposes the name and type of the property. It also allows the getting and setting of a value on an object. 28 | ### Example 29 | Using the same `User` object as before first we get the `TypeInfo` and the property we want. 30 | ```swift 31 | let info = try typeInfo(of: User.self) 32 | let property = try info.property(named: "username") 33 | ``` 34 | To get a value: 35 | ```swift 36 | let username = try property.get(from: user) 37 | ``` 38 | To set a value: 39 | ```swift 40 | try property.set(value: "newUsername", on: &user) 41 | ``` 42 | It's that easy! 🎉 43 | 44 | ## Factory 45 | Runtime also supports building an object from it's `Type`. Both structs and classes are supported. 46 | 47 | To build a `User` object: 48 | ```swift 49 | let user = try createInstance(type: User.self) 50 | ``` 51 | 52 | ## Function Info 53 | `FunctionInfo` exposes metadata about functions. Including number of arguments, argument types, return types, and whether it can throw an error. 54 | ### Example 55 | ```swift 56 | func doSomething(a: Int, b: Bool) throws -> String { 57 | return "" 58 | } 59 | 60 | let info = functionInfo(of: doSomething) 61 | ``` 62 | 63 | ## FAQ 64 | Q: When getting and setting a value does it work typeless? (i.e. object casted as `Any`) 65 | 66 | A: Yes! The whole library was designed with working typeless in mind. 67 | 68 | Q: When creating a new instance of a class is it still protected by ARC? 69 | 70 | A: Yes! The retain counts are set properly so ARC can do its job. 71 | 72 | ## Installation 73 | ### Cocoapods 74 | Runtime is available through [CocoaPods](http://cocoapods.org). To install 75 | it, simply add the following line to your Podfile: 76 | ```ruby 77 | pod 'Runtime' 78 | ``` 79 | ### Swift Package Manager 80 | 81 | You can install Runtime via [Swift Package Manager](https://swift.org/package-manager/) by adding the following line to your `Package.swift`: 82 | 83 | ```swift 84 | import PackageDescription 85 | 86 | let package = Package( 87 | [...] 88 | dependencies: [ 89 | .Package(url: "https://github.com/wickwirew/Runtime.git", majorVersion: XYZ) 90 | ] 91 | ) 92 | ``` 93 | 94 | ## Contributions 95 | Contributions are welcome and encouraged! 96 | 97 | ## Learn 98 | Want to know how it works? 99 | [Here's an article](https://medium.com/@weswickwire/creating-a-swift-runtime-library-3cc92fc486cc) on how it was implemented. 100 | 101 | Want to learn about Swift memory layout? 102 | [Mike Ash](https://github.com/mikeash) gave and awesome [talk](https://academy.realm.io/posts/goto-mike-ash-exploring-swift-memory-layout/) on just that. 103 | 104 | ## License 105 | Runtime is available under the MIT license. See the LICENSE file for more info. 106 | -------------------------------------------------------------------------------- /Tests/RuntimeTests/FactoryTests.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import XCTest 24 | @testable import Runtime 25 | 26 | class FactoryTests: XCTestCase { 27 | 28 | static var allTests: [(String, (FactoryTests) -> () throws -> Void)] { 29 | return [ 30 | ("testStruct", testStruct), 31 | ("testStructUntyped", testStructUntyped), 32 | ("testClass", testClass), 33 | ("testGenericClass", testGenericClass) 34 | ] 35 | } 36 | 37 | func testStruct() throws { 38 | let person: PersonStruct = try createInstance() 39 | XCTAssert(person.firstname == "") 40 | XCTAssert(person.lastname == "") 41 | XCTAssert(person.age == 0) 42 | XCTAssert(person.pet.name == "") 43 | XCTAssert(person.pet.age == 0) 44 | XCTAssert(person.favoriteNumbers == []) 45 | } 46 | 47 | func testStructUntyped() throws { 48 | let result = try createInstance(of: PersonStruct.self) 49 | let person = result as! PersonStruct 50 | XCTAssert(person.firstname == "") 51 | XCTAssert(person.lastname == "") 52 | XCTAssert(person.age == 0) 53 | XCTAssert(person.pet.name == "") 54 | XCTAssert(person.pet.age == 0) 55 | XCTAssert(person.favoriteNumbers == []) 56 | } 57 | 58 | func testClass() throws { 59 | let person: PersonClass = try createInstance() 60 | XCTAssert(person.firstname == "") 61 | XCTAssert(person.lastname == "") 62 | XCTAssert(person.age == 0) 63 | XCTAssert(person.pet.name == "") 64 | XCTAssert(person.pet.age == 0) 65 | XCTAssert(person.favoriteNumbers == []) 66 | } 67 | 68 | func testGenericClass() throws { 69 | class B {} 70 | class A { let a: Int = 0; let b = B() } 71 | let a: A = try createInstance() 72 | XCTAssert(a.a == 0) 73 | } 74 | } 75 | 76 | fileprivate struct PersonStruct { 77 | var firstname = "Jobie" 78 | var lastname = "Gillis" 79 | var age = 40 80 | var pet = PetStruct() 81 | var favoriteNumbers = [1, 2, 3, 4, 5] 82 | } 83 | 84 | fileprivate struct PetStruct { 85 | var name = "Nacho" 86 | var age = 12 87 | init() {} 88 | init(name: String, age: Int) { 89 | self.name = name 90 | self.age = age 91 | } 92 | } 93 | 94 | fileprivate class PersonClass { 95 | var firstname = "Jobie" 96 | var lastname = "Gillis" 97 | var age = 40 98 | var pet = PetClass() 99 | var favoriteNumbers = [1, 2, 3, 4, 5] 100 | } 101 | 102 | fileprivate class PetClass { 103 | var name = "Nacho" 104 | var age = 12 105 | init() {} 106 | init(name: String, age: Int) { 107 | self.name = name 108 | self.age = age 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Tests/RuntimeTests/ValuePointerTests.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import XCTest 24 | @testable import Runtime 25 | 26 | class ValuePointerTests: XCTestCase { 27 | 28 | static var allTests: [(String, (ValuePointerTests) -> () throws -> Void)] { 29 | return [ 30 | ("testStructValuePointer", testStructValuePointer), 31 | ("testProtocolStructValuePointer", testProtocolStructValuePointer), 32 | ("testClassValuePointer", testClassValuePointer), 33 | ("testProtocolClassValuePointer", testProtocolClassValuePointer), 34 | ("testAnyClassValuePointer", testAnyClassValuePointer), 35 | ("testAnyStructValuePointer", testAnyStructValuePointer) 36 | ] 37 | } 38 | 39 | func testStructValuePointer() throws { 40 | var person = PersonStruct() 41 | try withValuePointer(of: &person) { p in 42 | XCTAssert(p.assumingMemoryBound(to: String.self).pointee == "Wes") 43 | } 44 | } 45 | 46 | func testProtocolStructValuePointer() throws { 47 | var person: PersonProtocol = PersonStruct() 48 | try withValuePointer(of: &person) { p in 49 | XCTAssert(p.assumingMemoryBound(to: String.self).pointee == "Wes") 50 | } 51 | } 52 | 53 | func testClassValuePointer() throws { 54 | var person = PersonClass() 55 | try withValuePointer(of: &person) { p in 56 | let base = p.advanced(by: existentialHeaderSize) 57 | XCTAssert(base.assumingMemoryBound(to: String.self).pointee == "Wes") 58 | } 59 | } 60 | 61 | func testProtocolClassValuePointer() throws { 62 | var person: PersonProtocol = PersonClass() 63 | try withValuePointer(of: &person) { p in 64 | let base = p.advanced(by: existentialHeaderSize) 65 | XCTAssert(base.assumingMemoryBound(to: String.self).pointee == "Wes") 66 | } 67 | } 68 | 69 | func testAnyClassValuePointer() throws { 70 | var person: Any = PersonClass() 71 | try withValuePointer(of: &person) { p in 72 | let base = p.advanced(by: existentialHeaderSize) 73 | XCTAssert(base.assumingMemoryBound(to: String.self).pointee == "Wes") 74 | } 75 | } 76 | 77 | func testAnyStructValuePointer() throws { 78 | var person: Any = PersonStruct() 79 | try withValuePointer(of: &person) { p in 80 | XCTAssert(p.assumingMemoryBound(to: String.self).pointee == "Wes") 81 | } 82 | } 83 | } 84 | 85 | fileprivate protocol PersonProtocol { 86 | var fistname: String { get set } 87 | var lastname: String { get set } 88 | var age: Int { get set } 89 | } 90 | 91 | fileprivate struct PersonStruct: PersonProtocol { 92 | var fistname = "Wes" 93 | var lastname = "Wickwire" 94 | var age = 25 95 | } 96 | 97 | fileprivate class PersonClass: PersonProtocol { 98 | var fistname = "Wes" 99 | var lastname = "Wickwire" 100 | var age = 25 101 | } 102 | -------------------------------------------------------------------------------- /Sources/Runtime/Metadata/NominalMetadataType.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | protocol NominalMetadataType: MetadataType where Layout: NominalMetadataLayoutType { 24 | 25 | /// The offset of the generic type vector in pointer sized words from the 26 | /// start of the metadata record. 27 | var genericArgumentOffset: Int { get } 28 | } 29 | 30 | extension NominalMetadataType { 31 | 32 | var genericArgumentOffset: Int { 33 | // default to 2. This would put it right after the type descriptor which is valid 34 | // for all types except for classes 35 | return 2 36 | } 37 | 38 | var isGeneric: Bool { 39 | return (pointer.pointee.typeDescriptor.pointee.flags & 0x80) != 0 40 | } 41 | 42 | mutating func mangledName() -> String { 43 | return String(cString: pointer.pointee.typeDescriptor.pointee.mangledName.advanced()) 44 | } 45 | 46 | mutating func numberOfFields() -> Int { 47 | return Int(pointer.pointee.typeDescriptor.pointee.numberOfFields) 48 | } 49 | 50 | mutating func fieldOffsets() -> [Int] { 51 | return pointer.pointee.typeDescriptor.pointee 52 | .offsetToTheFieldOffsetVector 53 | .vector(metadata: pointer.raw.assumingMemoryBound(to: Int.self), n: numberOfFields()) 54 | .map(numericCast) 55 | } 56 | 57 | mutating func properties() -> [PropertyInfo] { 58 | let offsets = fieldOffsets() 59 | let fieldDescriptor = pointer.pointee.typeDescriptor.pointee 60 | .fieldDescriptor 61 | .advanced() 62 | 63 | let genericVector = genericArgumentVector() 64 | 65 | return (0.. UnsafeMutableBufferPointer { 85 | guard isGeneric else { return .init(start: nil, count: 0) } 86 | 87 | let count = pointer.pointee 88 | .typeDescriptor 89 | .pointee 90 | .genericContextHeader 91 | .base 92 | .numberOfParams 93 | return genericArgumentVector().buffer(n: Int(count)) 94 | } 95 | 96 | func genericArgumentVector() -> UnsafeMutablePointer { 97 | return pointer 98 | .advanced(by: genericArgumentOffset, wordSize: MemoryLayout.size) 99 | .assumingMemoryBound(to: Any.Type.self) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Sources/Runtime/Metadata/ClassMetadata.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | struct AnyClassMetadata { 24 | 25 | var pointer: UnsafeMutablePointer 26 | 27 | init(type: Any.Type) { 28 | pointer = unsafeBitCast(type, to: UnsafeMutablePointer.self) 29 | } 30 | 31 | func asClassMetadata() -> ClassMetadata? { 32 | guard pointer.pointee.isSwiftClass else { 33 | return nil 34 | } 35 | let ptr = pointer.raw.assumingMemoryBound(to: ClassMetadataLayout.self) 36 | return ClassMetadata(pointer: ptr) 37 | } 38 | } 39 | 40 | struct ClassMetadata: NominalMetadataType { 41 | 42 | var pointer: UnsafeMutablePointer 43 | 44 | var hasResilientSuperclass: Bool { 45 | let typeDescriptor = pointer.pointee.typeDescriptor 46 | return ((typeDescriptor.pointee.flags >> 16) & 0x2000) != 0 47 | } 48 | 49 | var areImmediateMembersNegative: Bool { 50 | let typeDescriptor = pointer.pointee.typeDescriptor 51 | return ((typeDescriptor.pointee.flags >> 16) & 0x1000) != 0 52 | } 53 | 54 | var genericArgumentOffset: Int { 55 | let typeDescriptor = pointer.pointee.typeDescriptor 56 | 57 | if !hasResilientSuperclass { 58 | return areImmediateMembersNegative 59 | ? -Int(typeDescriptor.pointee.negativeSizeAndBoundsUnion.metadataNegativeSizeInWords) 60 | : Int(typeDescriptor.pointee.metadataPositiveSizeInWords - typeDescriptor.pointee.numImmediateMembers) 61 | } 62 | 63 | /* 64 | let storedBounds = typeDescriptor.pointee 65 | .negativeSizeAndBoundsUnion 66 | .resilientMetadataBounds() 67 | .pointee 68 | .advanced() 69 | .pointee 70 | */ 71 | 72 | // To do this something like `computeMetadataBoundsFromSuperclass` in Metadata.cpp 73 | // will need to be implemented. To do that we also need to get the resilient superclass 74 | // from the trailing objects. 75 | fatalError("Cannot get the `genericArgumentOffset` for classes with a resilient superclass") 76 | } 77 | 78 | func superClassMetadata() -> AnyClassMetadata? { 79 | let superClass = pointer.pointee.superClass 80 | guard superClass != swiftObject() else { 81 | return nil 82 | } 83 | return AnyClassMetadata(type: superClass) 84 | } 85 | 86 | mutating func toTypeInfo() -> TypeInfo { 87 | var info = TypeInfo(metadata: self) 88 | info.mangledName = mangledName() 89 | info.properties = properties() 90 | info.genericTypes = Array(genericArguments()) 91 | 92 | var superClass = superClassMetadata()?.asClassMetadata() 93 | while var sc = superClass { 94 | info.inheritance.append(sc.type) 95 | let superInfo = sc.toTypeInfo() 96 | info.properties.append(contentsOf: superInfo.properties) 97 | superClass = sc.superClassMetadata()?.asClassMetadata() 98 | } 99 | 100 | return info 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /cmake/modules/SwiftSupport.cmake: -------------------------------------------------------------------------------- 1 | 2 | include(CMakeParseArguments) 3 | 4 | # Returns the architecture name in a variable 5 | # 6 | # Usage: 7 | # swift_get_host_arch(result_var_name) 8 | # 9 | # Sets ${result_var_name} with the converted architecture name derived from 10 | # CMAKE_SYSTEM_PROCESSOR. 11 | function(swift_get_host_arch result_var_name) 12 | if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") 13 | set("${result_var_name}" "x86_64" PARENT_SCOPE) 14 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64") 15 | set("${result_var_name}" "aarch64" PARENT_SCOPE) 16 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64") 17 | set("${result_var_name}" "powerpc64" PARENT_SCOPE) 18 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64le") 19 | set("${result_var_name}" "powerpc64le" PARENT_SCOPE) 20 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "s390x") 21 | set("${result_var_name}" "s390x" PARENT_SCOPE) 22 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv6l") 23 | set("${result_var_name}" "armv6" PARENT_SCOPE) 24 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") 25 | set("${result_var_name}" "armv7" PARENT_SCOPE) 26 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7-a") 27 | set("${result_var_name}" "armv7" PARENT_SCOPE) 28 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64") 29 | set("${result_var_name}" "x86_64" PARENT_SCOPE) 30 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "IA64") 31 | set("${result_var_name}" "itanium" PARENT_SCOPE) 32 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86") 33 | set("${result_var_name}" "i686" PARENT_SCOPE) 34 | elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686") 35 | set("${result_var_name}" "i686" PARENT_SCOPE) 36 | else() 37 | message(FATAL_ERROR "Unrecognized architecture on host system: ${CMAKE_SYSTEM_PROCESSOR}") 38 | endif() 39 | endfunction() 40 | 41 | # Returns the os name in a variable 42 | # 43 | # Usage: 44 | # get_swift_host_os(result_var_name) 45 | # 46 | # 47 | # Sets ${result_var_name} with the converted OS name derived from 48 | # CMAKE_SYSTEM_NAME. 49 | function(get_swift_host_os result_var_name) 50 | if(CMAKE_SYSTEM_NAME STREQUAL Darwin) 51 | set(${result_var_name} macosx PARENT_SCOPE) 52 | else() 53 | string(TOLOWER ${CMAKE_SYSTEM_NAME} cmake_system_name_lc) 54 | set(${result_var_name} ${cmake_system_name_lc} PARENT_SCOPE) 55 | endif() 56 | endfunction() 57 | 58 | function(swift_install) 59 | set(options) 60 | set(single_parameter_options EXPORT) 61 | set(multiple_parameter_options TARGETS) 62 | 63 | cmake_parse_arguments(SI 64 | "${options}" 65 | "${single_parameter_options}" 66 | "${multiple_parameter_options}" 67 | ${ARGN}) 68 | 69 | list(LENGTH ${SI_TARGETS} si_num_targets) 70 | if(si_num_targets GREATER 1) 71 | message(SEND_ERROR "swift_install only supports a single target at a time") 72 | endif() 73 | 74 | get_swift_host_os(swift_os) 75 | get_target_property(type ${SI_TARGETS} TYPE) 76 | 77 | if(type STREQUAL STATIC_LIBRARY) 78 | set(swift_dir swift_static) 79 | else() 80 | set(swift_dir swift) 81 | endif() 82 | 83 | install(TARGETS ${SI_TARGETS} 84 | EXPORT ${SI_EXPORT} 85 | ARCHIVE DESTINATION lib/${swift_dir}/${swift_os} 86 | LIBRARY DESTINATION lib/${swift_dir}/${swift_os} 87 | RUNTIME DESTINATION bin) 88 | if(type STREQUAL EXECUTABLE) 89 | return() 90 | endif() 91 | 92 | swift_get_host_arch(swift_arch) 93 | get_target_property(module_name ${SI_TARGETS} Swift_MODULE_NAME) 94 | if(NOT module_name) 95 | set(module_name ${SI_TARGETS}) 96 | endif() 97 | 98 | if(CMAKE_SYSTEM_NAME STREQUAL Darwin) 99 | install(FILES 100 | $/${module_name}.swiftdoc 101 | DESTINATION lib/${swift_dir}/${swift_os}/${module_name}.swiftmodule 102 | RENAME ${swift_arch}.swiftdoc) 103 | install(FILES 104 | $/${module_name}.swiftmodule 105 | DESTINATION lib/${swift_dir}/${swift_os}/${module_name}.swiftmodule 106 | RENAME ${swift_arch}.swiftmodule) 107 | else() 108 | install(FILES 109 | $/${module_name}.swiftdoc 110 | $/${module_name}.swiftmodule 111 | DESTINATION lib/${swift_dir}/${swift_os}/${swift_arch}) 112 | endif() 113 | endfunction() -------------------------------------------------------------------------------- /Sources/Runtime/Factory/Factory.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #if canImport(CRuntime) 24 | import CRuntime 25 | #endif 26 | 27 | public func createInstance(constructor: ((PropertyInfo) throws -> Any)? = nil) throws -> T { 28 | if let value = try createInstance(of: T.self, constructor: constructor) as? T { 29 | return value 30 | } 31 | 32 | throw RuntimeError.unableToBuildType(type: T.self) 33 | } 34 | 35 | public func createInstance(of type: Any.Type, constructor: ((PropertyInfo) throws -> Any)? = nil) throws -> Any { 36 | 37 | if let defaultConstructor = type as? DefaultConstructor.Type { 38 | return defaultConstructor.init() 39 | } 40 | 41 | let kind = Kind(type: type) 42 | switch kind { 43 | case .struct: 44 | return try buildStruct(type: type, constructor: constructor) 45 | case .class: 46 | return try buildClass(type: type) 47 | default: 48 | throw RuntimeError.unableToBuildType(type: type) 49 | } 50 | } 51 | 52 | func buildStruct(type: Any.Type, constructor: ((PropertyInfo) throws -> Any)? = nil) throws -> Any { 53 | let info = try typeInfo(of: type) 54 | let pointer = UnsafeMutableRawPointer.allocate(byteCount: info.size, alignment: info.alignment) 55 | defer { pointer.deallocate() } 56 | try setProperties(typeInfo: info, pointer: pointer, constructor: constructor) 57 | return getters(type: type).get(from: pointer) 58 | } 59 | 60 | func buildClass(type: Any.Type) throws -> Any { 61 | var md = ClassMetadata(type: type) 62 | let info = md.toTypeInfo() 63 | let metadata = unsafeBitCast(type, to: UnsafeRawPointer.self) 64 | let instanceSize = Int(md.pointer.pointee.instanceSize) 65 | 66 | // https://github.com/wickwirew/Runtime/issues/49 67 | // Docs specify that the alignment should be "always one less than a power of 2 that's at least alignof(void*)" 68 | // https://github.com/apple/swift/blob/7123d2614b5f222d03b3762cb110d27a9dd98e24/include/swift/Runtime/HeapObject.h#L56-L57 69 | // We could use md.alignment and deduct 1, or just use the instanceAlignmentMask from the ClassMetadata. 70 | let alignmentMask = Int(md.pointer.pointee.instanceAlignmentMask) 71 | 72 | guard let value = swift_allocObject(metadata, instanceSize, alignmentMask) else { 73 | throw RuntimeError.unableToBuildType(type: type) 74 | } 75 | 76 | try setProperties(typeInfo: info, pointer: UnsafeMutableRawPointer(mutating: value)) 77 | 78 | return unsafeBitCast(value, to: AnyObject.self) 79 | } 80 | 81 | func setProperties(typeInfo: TypeInfo, 82 | pointer: UnsafeMutableRawPointer, 83 | constructor: ((PropertyInfo) throws -> Any)? = nil) throws { 84 | for property in typeInfo.properties { 85 | let value = try constructor.map { (resolver) -> Any in 86 | return try resolver(property) 87 | } ?? defaultValue(of: property.type) 88 | 89 | let valuePointer = pointer.advanced(by: property.offset) 90 | let sets = setters(type: property.type) 91 | sets.set(value: value, pointer: valuePointer, initialize: true) 92 | } 93 | } 94 | 95 | func defaultValue(of type: Any.Type) throws -> Any { 96 | 97 | if let constructable = type as? DefaultConstructor.Type { 98 | return constructable.init() 99 | } else if let isOptional = type as? ExpressibleByNilLiteral.Type { 100 | return isOptional.init(nilLiteral: ()) 101 | } 102 | 103 | return try createInstance(of: type) 104 | } 105 | -------------------------------------------------------------------------------- /Tests/RuntimeTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | extension FactoryTests { 4 | static let __allTests = [ 5 | ("testStruct", testStruct), 6 | ("testStructUntyped", testStructUntyped), 7 | ("testClass", testClass), 8 | ("testGenericClass", testGenericClass) 9 | ] 10 | } 11 | 12 | extension GetSetClassTests { 13 | static let __allTests = [ 14 | ("testGet", testGet), 15 | ("testGetArray", testGetArray), 16 | ("testGetArrayUntyped", testGetArrayUntyped), 17 | ("testGetArrayUntypedObject", testGetArrayUntypedObject), 18 | ("testGetArrayUntypedValue", testGetArrayUntypedValue), 19 | ("testGetClass", testGetClass), 20 | ("testGetClassUntyped", testGetClassUntyped), 21 | ("testGetClassUntypedObject", testGetClassUntypedObject), 22 | ("testGetClassUntypedValue", testGetClassUntypedValue), 23 | ("testGetUntyped", testGetUntyped), 24 | ("testGetUntypedObject", testGetUntypedObject), 25 | ("testGetUntypedValue", testGetUntypedValue), 26 | ("testNSObjectBaseClass", testNSObjectBaseClass), 27 | ("testSet", testSet), 28 | ("testSetArray", testSetArray), 29 | ("testSetArrayUntyped", testSetArrayUntyped), 30 | ("testSetArrayUntypedObject", testSetArrayUntypedObject), 31 | ("testSetArrayUntypedValue", testSetArrayUntypedValue), 32 | ("testSetClass", testSetClass), 33 | ("testSetClassUntyped", testSetClassUntyped), 34 | ("testSetClassUntypedObject", testSetClassUntypedObject), 35 | ("testSetClassUntypedValue", testSetClassUntypedValue), 36 | ("testSetUntyped", testSetUntyped), 37 | ("testSetUntypedObject", testSetUntypedObject), 38 | ("testSetUntypedValue", testSetUntypedValue) 39 | ] 40 | } 41 | 42 | extension GetSetStructTests { 43 | static let __allTests = [ 44 | ("testGet", testGet), 45 | ("testGetSimple", testGetSimple), 46 | ("testGetArray", testGetArray), 47 | ("testGetArrayUntyped", testGetArrayUntyped), 48 | ("testGetArrayUntypedObject", testGetArrayUntypedObject), 49 | ("testGetArrayUntypedValue", testGetArrayUntypedValue), 50 | ("testGetStruct", testGetStruct), 51 | ("testGetStructUntyped", testGetStructUntyped), 52 | ("testGetStructUntypedObject", testGetStructUntypedObject), 53 | ("testGetStructUntypedValue", testGetStructUntypedValue), 54 | ("testGetUntyped", testGetUntyped), 55 | ("testGetUntypedObject", testGetUntypedObject), 56 | ("testGetUntypedValue", testGetUntypedValue), 57 | ("testSet", testSet), 58 | ("testSetArray", testSetArray), 59 | ("testSetArrayUntyped", testSetArrayUntyped), 60 | ("testSetArrayUntypedObject", testSetArrayUntypedObject), 61 | ("testSetArrayUntypedValue", testSetArrayUntypedValue), 62 | ("testSetCasting", testSetCasting), 63 | ("testSetCastingFailure", testSetCastingFailure), 64 | ("testSetStruct", testSetStruct), 65 | ("testSetStructUntyped", testSetStructUntyped), 66 | ("testSetStructUntypedObject", testSetStructUntypedObject), 67 | ("testSetStructUntypedValue", testSetStructUntypedValue), 68 | ("testSetUntyped", testSetUntyped), 69 | ("testSetUntypedObject", testSetUntypedObject), 70 | ("testSetUntypedValue", testSetUntypedValue) 71 | ] 72 | } 73 | 74 | extension MetadataTests { 75 | static let __allTests = [ 76 | ("testClass", testClass), 77 | ("testResilientClass", testResilientClass), 78 | ("testStruct", testStruct), 79 | ("testGenericStruct", testGenericStruct), 80 | ("testNestedStruct", testNestedStruct), 81 | ("testProtocol", testProtocol), 82 | ("testTuple", testTuple), 83 | ("testTupleNoLabels", testTupleNoLabels), 84 | ("testFunction", testFunction), 85 | ("testFunctionThrows", testFunctionThrows), 86 | ("testVoidFunction", testVoidFunction), 87 | ("testEnum", testEnum), 88 | ("testEnumTestEnumWithPayload", testEnumTestEnumWithPayload), 89 | ("testObjcEnum", testObjcEnum), 90 | ("testOptional", testOptional) 91 | ] 92 | } 93 | 94 | extension ValuePointerTests { 95 | static let __allTests = [ 96 | ("testAnyClassValuePointer", testAnyClassValuePointer), 97 | ("testAnyStructValuePointer", testAnyStructValuePointer), 98 | ("testClassValuePointer", testClassValuePointer), 99 | ("testProtocolClassValuePointer", testProtocolClassValuePointer), 100 | ("testProtocolStructValuePointer", testProtocolStructValuePointer), 101 | ("testStructValuePointer", testStructValuePointer) 102 | ] 103 | } 104 | 105 | extension ValueWitnessTableTests { 106 | static let __allTests = [ 107 | ("testAlignment", testAlignment), 108 | ("testSize", testSize), 109 | ("testStride", testStride) 110 | ] 111 | } 112 | 113 | #if !os(macOS) && !os(iOS) 114 | public func __allTests() -> [XCTestCaseEntry] { 115 | return [ 116 | testCase(FactoryTests.__allTests), 117 | testCase(GetSetClassTests.__allTests), 118 | testCase(GetSetStructTests.__allTests), 119 | testCase(MetadataTests.__allTests), 120 | testCase(ValuePointerTests.__allTests), 121 | testCase(ValueWitnessTableTests.__allTests) 122 | ] 123 | } 124 | #endif 125 | -------------------------------------------------------------------------------- /Tests/RuntimeTests/MetadataTests.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #if canImport(Foundation) 24 | import Foundation 25 | #endif 26 | 27 | import XCTest 28 | @testable import Runtime 29 | 30 | class MetadataTests: XCTestCase { 31 | 32 | static var allTests: [(String, (MetadataTests) -> () throws -> Void)] { 33 | return [ 34 | ("testClass", testClass), 35 | ("testResilientClass", testResilientClass), 36 | ("testStruct", testStruct), 37 | ("testGenericStruct", testGenericStruct), 38 | ("testNestedStruct", testNestedStruct), 39 | ("testProtocol", testProtocol), 40 | ("testTuple", testTuple), 41 | ("testTupleNoLabels", testTupleNoLabels), 42 | ("testFunction", testFunction), 43 | ("testFunctionThrows", testFunctionThrows), 44 | ("testVoidFunction", testVoidFunction), 45 | ("testEnum", testEnum) 46 | ] 47 | } 48 | 49 | func testClass() { 50 | var md = ClassMetadata(type: MyClass.self) 51 | let info = md.toTypeInfo() 52 | 53 | // see comment in ClassMetadataLayout.swift 54 | #if !swift(>=5.4) || canImport(ObjectiveC) 55 | XCTAssert(md.genericArgumentOffset == 15) 56 | #else 57 | XCTAssert(md.genericArgumentOffset == 15 - 3) 58 | #endif 59 | 60 | XCTAssert(info.properties.first {$0.name == "baseProperty"} != nil) 61 | XCTAssert(info.inheritance[0] == BaseClass.self) 62 | XCTAssert(info.superClass == BaseClass.self) 63 | XCTAssert(info.mangledName != "") 64 | XCTAssert(info.kind == .class) 65 | XCTAssert(info.type == MyClass.self) 66 | XCTAssert(info.properties.count == 3) 67 | XCTAssert(info.size == MemoryLayout>.size) 68 | XCTAssert(info.alignment == MemoryLayout>.alignment) 69 | XCTAssert(info.stride == MemoryLayout>.stride) 70 | XCTAssert(info.genericTypes.count == 1) 71 | XCTAssert(info.genericTypes[0] == Int.self) 72 | } 73 | 74 | func testResilientClass() { 75 | #if canImport(Darwin) 76 | class DerivedResilient: JSONEncoder {} 77 | let md1 = ClassMetadata(type: BaseClass.self) 78 | let md2 = ClassMetadata(type: JSONDecoder.self) 79 | let md3 = ClassMetadata(type: DerivedResilient.self) 80 | XCTAssertFalse(md1.hasResilientSuperclass) 81 | XCTAssertFalse(md2.hasResilientSuperclass) 82 | XCTAssertTrue(md3.hasResilientSuperclass) 83 | #endif 84 | } 85 | 86 | func testGenericStruct() { 87 | struct A { let b: B } 88 | var md = StructMetadata(type: A.self) 89 | let args = md.genericArguments() 90 | let props = md.properties() 91 | XCTAssert(args.count == 7) 92 | XCTAssert(args[0] == Int.self) 93 | XCTAssert(args[1] == String.self) 94 | XCTAssert(args[2] == Bool.self) 95 | XCTAssert(args[3] == Int.self) 96 | XCTAssert(props.count == 1) 97 | XCTAssert(props[0].type == Int.self) 98 | } 99 | 100 | func testStruct() { 101 | struct A { 102 | let a, b, c, d: Int 103 | var e: Int 104 | } 105 | 106 | var md = StructMetadata(type: A.self) 107 | let info = md.toTypeInfo() 108 | XCTAssert(info.genericTypes.count == 0) 109 | XCTAssert(info.kind == .struct) 110 | XCTAssert(info.type == A.self) 111 | XCTAssert(info.properties.count == 5) 112 | XCTAssert(info.size == MemoryLayout.size) 113 | XCTAssert(info.alignment == MemoryLayout.alignment) 114 | XCTAssert(info.stride == MemoryLayout.stride) 115 | XCTAssert(!info.properties[0].isVar) 116 | XCTAssert(info.properties[4].isVar) 117 | } 118 | 119 | // https://github.com/wickwirew/Runtime/issues/42 120 | func testNestedStruct() { 121 | 122 | let nest: () -> Void = { 123 | 124 | struct NestedA { 125 | let a, b, c, d: Int 126 | var e: Int 127 | } 128 | 129 | var md = StructMetadata(type: NestedA.self) 130 | let info = md.toTypeInfo() 131 | XCTAssert(info.genericTypes.count == 0) 132 | XCTAssert(info.kind == .struct) 133 | XCTAssert(info.type == NestedA.self) 134 | XCTAssert(info.properties.count == 5) 135 | XCTAssert(info.size == MemoryLayout.size) 136 | XCTAssert(info.alignment == MemoryLayout.alignment) 137 | XCTAssert(info.stride == MemoryLayout.stride) 138 | XCTAssert(!info.properties[0].isVar) 139 | XCTAssert(info.properties[4].isVar) 140 | } 141 | 142 | nest() 143 | } 144 | 145 | func testProtocol() { 146 | var md = ProtocolMetadata(type: MyProtocol.self) 147 | let info = md.toTypeInfo() 148 | XCTAssert(info.kind == .existential) 149 | XCTAssert(info.type == MyProtocol.self) 150 | XCTAssert(info.size == MemoryLayout.size) 151 | XCTAssert(info.alignment == MemoryLayout.alignment) 152 | XCTAssert(info.stride == MemoryLayout.stride) 153 | } 154 | 155 | func testTuple() { 156 | let type = (a: Int, b: Bool, c: String).self 157 | var md = TupleMetadata(type: type) 158 | let info = md.toTypeInfo() 159 | XCTAssert(info.kind == .tuple) 160 | XCTAssert(info.type == (a: Int, b: Bool, c: String).self) 161 | XCTAssert(info.properties.count == 3) 162 | XCTAssert(info.size == MemoryLayout<(a: Int, b: Bool, c: String)>.size) 163 | XCTAssert(info.alignment == MemoryLayout<(a: Int, b: Bool, c: String)>.alignment) 164 | XCTAssert(info.stride == MemoryLayout<(a: Int, b: Bool, c: String)>.stride) 165 | } 166 | 167 | func testTupleNoLabels() { 168 | let type = (Int, Bool, String).self 169 | let md = TupleMetadata(type: type) 170 | XCTAssert(md.labels() == ["", "", ""]) 171 | XCTAssert(md.numberOfElements() == 3) 172 | } 173 | 174 | func testFunction() throws { 175 | let info = try functionInfo(of: myFunc) 176 | XCTAssert(info.numberOfArguments == 3) 177 | XCTAssert(info.argumentTypes[0] == Int.self) 178 | XCTAssert(info.argumentTypes[1] == Bool.self) 179 | XCTAssert(info.argumentTypes[2] == String.self) 180 | XCTAssert(info.returnType == String.self) 181 | XCTAssert(!info.throws) 182 | } 183 | 184 | func testFunctionThrows() { 185 | let t = ((Int) throws -> String).self 186 | let md = FunctionMetadata(type: t) 187 | let info = md.info() 188 | XCTAssert(info.numberOfArguments == 1) 189 | XCTAssert(info.argumentTypes[0] == Int.self) 190 | XCTAssert(info.returnType == String.self) 191 | XCTAssert(info.throws) 192 | } 193 | 194 | func testVoidFunction() { 195 | let t = type(of: voidFunction) 196 | let md = FunctionMetadata(type: t) 197 | let info = md.info() 198 | XCTAssert(info.numberOfArguments == 0) 199 | } 200 | 201 | func testEnum() { 202 | var md = EnumMetadata(type: MyEnum.self) 203 | let info = md.toTypeInfo() 204 | XCTAssert(info.cases[0].name == "a") 205 | XCTAssert(info.cases[1].name == "b") 206 | XCTAssert(info.cases[2].name == "c") 207 | XCTAssert(info.cases[3].name == "d") 208 | } 209 | 210 | func testEnumTestEnumWithPayload() { 211 | enum Foo { 212 | case a,b,c 213 | case hasPayload(Int) 214 | case hasTuplePayload(Bool, Int) 215 | } 216 | 217 | var md = EnumMetadata(type: Foo.self) 218 | let info = md.toTypeInfo() 219 | 220 | guard let hasPayload = info.cases.first(where: { $0.name == "hasPayload" }), 221 | let hasTuplePayload = info.cases.first(where: { $0.name == "hasTuplePayload" }) else { 222 | return XCTFail("Missing payload cases") 223 | } 224 | 225 | XCTAssertEqual(md.numberOfCases, 5) 226 | XCTAssertEqual(md.numberOfPayloadCases, 2) 227 | XCTAssert(hasPayload.payloadType == Int.self) 228 | XCTAssert(hasTuplePayload.payloadType == (Bool, Int).self) 229 | } 230 | 231 | func testObjcEnum() { 232 | #if canImport(Foundation) 233 | var md = EnumMetadata(type: ComparisonResult.self) 234 | let info = md.toTypeInfo() 235 | XCTAssertEqual(info.numberOfEnumCases, 3) 236 | XCTAssertEqual(info.numberOfPayloadEnumCases, 0) 237 | #endif 238 | } 239 | 240 | func testOptional() throws { 241 | let info = try typeInfo(of: Double?.self) 242 | XCTAssert(info.cases[0].name == "some") 243 | XCTAssert(info.cases[1].name == "none") 244 | } 245 | } 246 | 247 | fileprivate enum MyEnum: Int { 248 | case a, b, c, d 249 | } 250 | 251 | func voidFunction() { 252 | 253 | } 254 | 255 | func myFunc(a: Int, b: Bool, c: String) -> String { 256 | return "" 257 | } 258 | 259 | fileprivate protocol MyProtocol { 260 | var a: Int { get set } 261 | func doSomething(value: Int) -> Bool 262 | } 263 | 264 | fileprivate class BaseClass { 265 | var baseProperty: Int = 0 266 | } 267 | 268 | fileprivate class MyClass: BaseClass { 269 | var property: String = "" 270 | var gen: T 271 | init(g: T) { 272 | gen = g 273 | } 274 | } 275 | 276 | fileprivate struct MyStruct { 277 | var a, b: Int 278 | var c: String 279 | var d: T 280 | } 281 | -------------------------------------------------------------------------------- /Tests/RuntimeTests/GetSetClassTests.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import XCTest 24 | @testable import Runtime 25 | 26 | class GetSetClassTests: XCTestCase { 27 | 28 | static var allTests: [(String, (GetSetClassTests) -> () throws -> Void)] { 29 | return [ 30 | ("testGet", testGet), 31 | ("testGetUntypedValue", testGetUntypedValue), 32 | ("testGetUntypedObject", testGetUntypedObject), 33 | ("testGetUntyped", testGetUntyped), 34 | ("testGetClass", testGetClass), 35 | ("testGetClassUntypedValue", testGetClassUntypedValue), 36 | ("testGetClassUntypedObject", testGetClassUntypedObject), 37 | ("testGetClassUntyped", testGetClassUntyped), 38 | ("testGetArray", testGetArray), 39 | ("testGetArrayUntypedValue", testGetArrayUntypedValue), 40 | ("testGetArrayUntypedObject", testGetArrayUntypedObject), 41 | ("testGetArrayUntyped", testGetArrayUntyped), 42 | 43 | ("testSet", testSet), 44 | ("testSetUntypedValue", testSetUntypedValue), 45 | ("testSetUntypedObject", testSetUntypedObject), 46 | ("testSetUntyped", testSetUntyped), 47 | ("testSetClass", testSetClass), 48 | ("testSetClassUntypedValue", testSetClassUntypedValue), 49 | ("testSetClassUntypedObject", testSetClassUntypedObject), 50 | ("testSetClassUntyped", testSetClassUntyped), 51 | ("testSetArray", testSetArray), 52 | ("testSetArrayUntypedValue", testSetArrayUntypedValue), 53 | ("testSetArrayUntypedObject", testSetArrayUntypedObject), 54 | ("testSetArrayUntyped", testSetArrayUntyped) 55 | ] 56 | } 57 | 58 | // swiftlint:disable force_cast 59 | func testGet() throws { 60 | let info = try typeInfo(of: Person.self) 61 | let firstname = try info.property(named: "firstname") 62 | let person = Person() 63 | let name: String = try firstname.get(from: person) 64 | XCTAssert(name == "Wes") 65 | } 66 | 67 | func testGetUntypedValue() throws { 68 | let info = try typeInfo(of: Person.self) 69 | let firstname = try info.property(named: "firstname") 70 | let person = Person() 71 | let name: Any = try firstname.get(from: person) 72 | XCTAssert((name as! String) == "Wes") 73 | } 74 | 75 | func testGetUntypedObject() throws { 76 | let info = try typeInfo(of: Person.self) 77 | let firstname = try info.property(named: "firstname") 78 | let person: Any = Person() 79 | let name: String = try firstname.get(from: person) 80 | XCTAssert(name == "Wes") 81 | } 82 | 83 | func testGetUntyped() throws { 84 | let info = try typeInfo(of: Person.self) 85 | let firstname = try info.property(named: "firstname") 86 | let person: Any = Person() 87 | let name: Any = try firstname.get(from: person) 88 | XCTAssert((name as! String) == "Wes") 89 | } 90 | 91 | func testGetClass() throws { 92 | let info = try typeInfo(of: Person.self) 93 | let pet = try info.property(named: "pet") 94 | let person = Person() 95 | let value: Pet = try pet.get(from: person) 96 | XCTAssert(value.name == "Marley") 97 | } 98 | 99 | func testGetClassUntypedValue() throws { 100 | let info = try typeInfo(of: Person.self) 101 | let pet = try info.property(named: "pet") 102 | let person = Person() 103 | let value: Any = try pet.get(from: person) 104 | XCTAssert((value as! Pet).name == "Marley") 105 | } 106 | 107 | func testGetClassUntypedObject() throws { 108 | let info = try typeInfo(of: Person.self) 109 | let pet = try info.property(named: "pet") 110 | let person: Any = Person() 111 | let value: Pet = try pet.get(from: person) 112 | XCTAssert(value.name == "Marley") 113 | } 114 | 115 | func testGetClassUntyped() throws { 116 | let info = try typeInfo(of: Person.self) 117 | let pet = try info.property(named: "pet") 118 | let person: Any = Person() 119 | let value: Any = try pet.get(from: person) 120 | XCTAssert((value as! Pet).name == "Marley") 121 | } 122 | 123 | func testGetArray() throws { 124 | let info = try typeInfo(of: Person.self) 125 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 126 | let person = Person() 127 | let value: [Int] = try favoriteNumbers.get(from: person) 128 | XCTAssert(value == [1, 2, 3, 4, 5]) 129 | } 130 | 131 | func testGetArrayUntypedValue() throws { 132 | let info = try typeInfo(of: Person.self) 133 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 134 | let person = Person() 135 | let value: Any = try favoriteNumbers.get(from: person) 136 | XCTAssert(value as! [Int] == [1, 2, 3, 4, 5]) 137 | } 138 | 139 | func testGetArrayUntypedObject() throws { 140 | let info = try typeInfo(of: Person.self) 141 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 142 | let person: Any = Person() 143 | let value: [Int] = try favoriteNumbers.get(from: person) 144 | XCTAssert(value == [1, 2, 3, 4, 5]) 145 | } 146 | 147 | func testGetArrayUntyped() throws { 148 | let info = try typeInfo(of: Person.self) 149 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 150 | let person: Any = Person() 151 | let value: Any = try favoriteNumbers.get(from: person) 152 | XCTAssert(value as! [Int] == [1, 2, 3, 4, 5]) 153 | } 154 | 155 | func testSet() throws { 156 | let info = try typeInfo(of: Person.self) 157 | let firstname = try info.property(named: "firstname") 158 | var person = Person() 159 | try firstname.set(value: "John", on: &person) 160 | XCTAssert(person.firstname == "John") 161 | } 162 | 163 | func testSetUntypedValue() throws { 164 | let info = try typeInfo(of: Person.self) 165 | let firstname = try info.property(named: "firstname") 166 | var person = Person() 167 | let new: Any = "John" 168 | try firstname.set(value: new, on: &person) 169 | XCTAssert(person.firstname == "John") 170 | } 171 | 172 | func testSetUntypedObject() throws { 173 | let info = try typeInfo(of: Person.self) 174 | let firstname = try info.property(named: "firstname") 175 | var person: Any = Person() 176 | try firstname.set(value: "John", on: &person) 177 | XCTAssert((person as! Person).firstname == "John") 178 | } 179 | 180 | func testSetUntyped() throws { 181 | let info = try typeInfo(of: Person.self) 182 | let firstname = try info.property(named: "firstname") 183 | var person: Any = Person() 184 | let new: Any = "John" 185 | try firstname.set(value: new, on: &person) 186 | XCTAssert((person as! Person).firstname == "John") 187 | } 188 | 189 | func testSetArray() throws { 190 | let info = try typeInfo(of: Person.self) 191 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 192 | var person = Person() 193 | let new = [5, 4, 3, 2, 1] 194 | try favoriteNumbers.set(value: new, on: &person) 195 | XCTAssert(person.favoriteNumbers == [5, 4, 3, 2, 1]) 196 | } 197 | 198 | func testSetArrayUntypedValue() throws { 199 | let info = try typeInfo(of: Person.self) 200 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 201 | var person = Person() 202 | let new = [5, 4, 3, 2, 1] 203 | try favoriteNumbers.set(value: new, on: &person) 204 | XCTAssert(person.favoriteNumbers == [5, 4, 3, 2, 1]) 205 | } 206 | 207 | func testSetArrayUntypedObject() throws { 208 | let info = try typeInfo(of: Person.self) 209 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 210 | var person: Any = Person() 211 | let new = [5, 4, 3, 2, 1] 212 | try favoriteNumbers.set(value: new, on: &person) 213 | XCTAssert((person as! Person).favoriteNumbers == [5, 4, 3, 2, 1]) 214 | } 215 | 216 | func testSetArrayUntyped() throws { 217 | let info = try typeInfo(of: Person.self) 218 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 219 | var person: Any = Person() 220 | let new = [5, 4, 3, 2, 1] 221 | try favoriteNumbers.set(value: new, on: &person) 222 | XCTAssert((person as! Person).favoriteNumbers == [5, 4, 3, 2, 1]) 223 | } 224 | 225 | func testSetClass() throws { 226 | let info = try typeInfo(of: Person.self) 227 | let pet = try info.property(named: "pet") 228 | var person = Person() 229 | let new = Pet(name: "Rex", age: 9) 230 | try pet.set(value: new, on: &person) 231 | XCTAssert(person.pet.name == "Rex") 232 | } 233 | 234 | func testSetClassUntypedValue() throws { 235 | let info = try typeInfo(of: Person.self) 236 | let pet = try info.property(named: "pet") 237 | var person = Person() 238 | let new = Pet(name: "Rex", age: 9) 239 | try pet.set(value: new, on: &person) 240 | XCTAssert(person.pet.name == "Rex") 241 | } 242 | 243 | func testSetClassUntypedObject() throws { 244 | let info = try typeInfo(of: Person.self) 245 | let pet = try info.property(named: "pet") 246 | var person: Any = Person() 247 | let new = Pet(name: "Rex", age: 9) 248 | try pet.set(value: new, on: &person) 249 | XCTAssert((person as! Person).pet.name == "Rex") 250 | } 251 | 252 | func testSetClassUntyped() throws { 253 | let info = try typeInfo(of: Person.self) 254 | let pet = try info.property(named: "pet") 255 | var person: Any = Person() 256 | let new = Pet(name: "Rex", age: 9) 257 | try pet.set(value: new, on: &person) 258 | XCTAssert((person as! Person).pet.name == "Rex") 259 | } 260 | 261 | /// Test case from: https://github.com/wickwirew/Runtime/issues/25 262 | func testNSObjectBaseClass() throws { 263 | 264 | class User: NSObject { 265 | let id: Int = 0 266 | let username: String = "" 267 | let email: String = "" 268 | } 269 | 270 | let info = try typeInfo(of: User.self) 271 | let property = try info.property(named: "username") 272 | 273 | XCTAssert(property.name == "username") 274 | XCTAssert(property.type == String.self) 275 | } 276 | // swiftlint:enable force_cast 277 | } 278 | 279 | fileprivate class Person { 280 | var firstname = "Wes" 281 | var lastname = "Wickwire" 282 | var age = 25 283 | var pet = Pet() 284 | var favoriteNumbers = [1, 2, 3, 4, 5] 285 | } 286 | 287 | fileprivate class Pet { 288 | var name = "Marley" 289 | var age = 12 290 | init() {} 291 | init(name: String, age: Int) { 292 | self.name = name 293 | self.age = age 294 | } 295 | } 296 | -------------------------------------------------------------------------------- /Tests/RuntimeTests/GetSetStructTests.swift: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2017 Wesley Wickwire 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import XCTest 24 | @testable import Runtime 25 | 26 | // swiftlint:disable type_body_length 27 | class GetSetStructTests: XCTestCase { 28 | 29 | static var allTests: [(String, (GetSetStructTests) -> () throws -> Void)] { 30 | return [ 31 | ("testGet", testGet), 32 | ("testGetSimple", testGetSimple), 33 | ("testGetUntypedValue", testGetUntypedValue), 34 | ("testGetUntypedObject", testGetUntypedObject), 35 | ("testGetUntyped", testGetUntyped), 36 | ("testGetStruct", testGetStruct), 37 | ("testGetStructUntypedValue", testGetStructUntypedValue), 38 | ("testGetStructUntypedObject", testGetStructUntypedObject), 39 | ("testGetStructUntyped", testGetStructUntyped), 40 | ("testGetArray", testGetArray), 41 | ("testGetArrayUntypedValue", testGetArrayUntypedValue), 42 | ("testGetArrayUntypedObject", testGetArrayUntypedObject), 43 | ("testGetArrayUntyped", testGetArrayUntyped), 44 | 45 | ("testSet", testSet), 46 | ("testSetUntypedValue", testSetUntypedValue), 47 | ("testSetUntypedObject", testSetUntypedObject), 48 | ("testSetUntyped", testSetUntyped), 49 | ("testSetStruct", testSetStruct), 50 | ("testSetStructUntypedValue", testSetStructUntypedValue), 51 | ("testSetStructUntypedObject", testSetStructUntypedObject), 52 | ("testSetStructUntyped", testSetStructUntyped), 53 | ("testSetArray", testSetArray), 54 | ("testSetArrayUntypedValue", testSetArrayUntypedValue), 55 | ("testSetArrayUntypedObject", testSetArrayUntypedObject), 56 | ("testSetArrayUntyped", testSetArrayUntyped) 57 | ] 58 | } 59 | 60 | // swiftlint:disable force_cast 61 | func testGet() throws { 62 | let info = try typeInfo(of: Person.self) 63 | let firstname = try info.property(named: "firstname") 64 | let person = Person() 65 | let name: String = try firstname.get(from: person) 66 | XCTAssert(name == "Wes") 67 | } 68 | 69 | func testGetSimple() throws { 70 | struct Test { let a: Int = 2 } 71 | let info = try typeInfo(of: Test.self) 72 | let a = try info.property(named: "a") 73 | let value = Test() 74 | let result: Int = try a.get(from: value) 75 | XCTAssert(result == 2) 76 | } 77 | 78 | func testGetUntypedValue() throws { 79 | let info = try typeInfo(of: Person.self) 80 | let firstname = try info.property(named: "firstname") 81 | let person = Person() 82 | let name: Any = try firstname.get(from: person) 83 | XCTAssert((name as! String) == "Wes") 84 | } 85 | 86 | func testGetUntypedObject() throws { 87 | let info = try typeInfo(of: Person.self) 88 | let firstname = try info.property(named: "firstname") 89 | let person: Any = Person() 90 | let name: String = try firstname.get(from: person) 91 | XCTAssert(name == "Wes") 92 | } 93 | 94 | func testGetUntyped() throws { 95 | let info = try typeInfo(of: Person.self) 96 | let firstname = try info.property(named: "firstname") 97 | let person: Any = Person() 98 | let name: Any = try firstname.get(from: person) 99 | XCTAssert((name as! String) == "Wes") 100 | } 101 | 102 | func testGetStruct() throws { 103 | let info = try typeInfo(of: Person.self) 104 | let pet = try info.property(named: "pet") 105 | let person = Person() 106 | let value: Pet = try pet.get(from: person) 107 | XCTAssert(value.name == "Marley") 108 | } 109 | 110 | func testGetStructUntypedValue() throws { 111 | let info = try typeInfo(of: Person.self) 112 | let pet = try info.property(named: "pet") 113 | let person = Person() 114 | let value: Any = try pet.get(from: person) 115 | XCTAssert((value as! Pet).name == "Marley") 116 | } 117 | 118 | func testGetStructUntypedObject() throws { 119 | let info = try typeInfo(of: Person.self) 120 | let pet = try info.property(named: "pet") 121 | let person: Any = Person() 122 | let value: Pet = try pet.get(from: person) 123 | XCTAssert(value.name == "Marley") 124 | } 125 | 126 | func testGetStructUntyped() throws { 127 | let info = try typeInfo(of: Person.self) 128 | let pet = try info.property(named: "pet") 129 | let person: Any = Person() 130 | let value: Any = try pet.get(from: person) 131 | XCTAssert((value as! Pet).name == "Marley") 132 | } 133 | 134 | func testGetArray() throws { 135 | let info = try typeInfo(of: Person.self) 136 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 137 | let person = Person() 138 | let value: [Int] = try favoriteNumbers.get(from: person) 139 | XCTAssert(value == [1, 2, 3, 4, 5]) 140 | } 141 | 142 | func testGetArrayUntypedValue() throws { 143 | let info = try typeInfo(of: Person.self) 144 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 145 | let person = Person() 146 | let value: Any = try favoriteNumbers.get(from: person) 147 | XCTAssert(value as! [Int] == [1, 2, 3, 4, 5]) 148 | } 149 | 150 | func testGetArrayUntypedObject() throws { 151 | let info = try typeInfo(of: Person.self) 152 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 153 | let person: Any = Person() 154 | let value: [Int] = try favoriteNumbers.get(from: person) 155 | XCTAssert(value == [1, 2, 3, 4, 5]) 156 | } 157 | 158 | func testGetArrayUntyped() throws { 159 | let info = try typeInfo(of: Person.self) 160 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 161 | let person: Any = Person() 162 | let value: Any = try favoriteNumbers.get(from: person) 163 | XCTAssert(value as! [Int] == [1, 2, 3, 4, 5]) 164 | } 165 | 166 | func testSet() throws { 167 | let info = try typeInfo(of: Person.self) 168 | let firstname = try info.property(named: "firstname") 169 | var person = Person() 170 | try firstname.set(value: "John", on: &person) 171 | XCTAssert(person.firstname == "John") 172 | } 173 | 174 | func testSetUntypedValue() throws { 175 | let info = try typeInfo(of: Person.self) 176 | let firstname = try info.property(named: "firstname") 177 | var person = Person() 178 | let new: Any = "John" 179 | try firstname.set(value: new, on: &person) 180 | XCTAssert(person.firstname == "John") 181 | } 182 | 183 | func testSetUntypedObject() throws { 184 | let info = try typeInfo(of: Person.self) 185 | let firstname = try info.property(named: "firstname") 186 | var person: Any = Person() 187 | try firstname.set(value: "John", on: &person) 188 | XCTAssert((person as! Person).firstname == "John") 189 | } 190 | 191 | func testSetUntyped() throws { 192 | let info = try typeInfo(of: Person.self) 193 | let firstname = try info.property(named: "firstname") 194 | var person: Any = Person() 195 | let new: Any = "John" 196 | try firstname.set(value: new, on: &person) 197 | XCTAssert((person as! Person).firstname == "John") 198 | } 199 | 200 | func testSetArray() throws { 201 | let info = try typeInfo(of: Person.self) 202 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 203 | var person = Person() 204 | let new = [5, 4, 3, 2, 1] 205 | try favoriteNumbers.set(value: new, on: &person) 206 | XCTAssert(person.favoriteNumbers == [5, 4, 3, 2, 1]) 207 | } 208 | 209 | func testSetArrayUntypedValue() throws { 210 | let info = try typeInfo(of: Person.self) 211 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 212 | var person = Person() 213 | let new = [5, 4, 3, 2, 1] 214 | try favoriteNumbers.set(value: new, on: &person) 215 | XCTAssert(person.favoriteNumbers == [5, 4, 3, 2, 1]) 216 | } 217 | 218 | func testSetArrayUntypedObject() throws { 219 | let info = try typeInfo(of: Person.self) 220 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 221 | var person: Any = Person() 222 | let new = [5, 4, 3, 2, 1] 223 | try favoriteNumbers.set(value: new, on: &person) 224 | XCTAssert((person as! Person).favoriteNumbers == [5, 4, 3, 2, 1]) 225 | } 226 | 227 | func testSetArrayUntyped() throws { 228 | let info = try typeInfo(of: Person.self) 229 | let favoriteNumbers = try info.property(named: "favoriteNumbers") 230 | var person: Any = Person() 231 | let new = [5, 4, 3, 2, 1] 232 | try favoriteNumbers.set(value: new, on: &person) 233 | XCTAssert((person as! Person).favoriteNumbers == [5, 4, 3, 2, 1]) 234 | } 235 | 236 | func testSetStruct() throws { 237 | let info = try typeInfo(of: Person.self) 238 | let pet = try info.property(named: "pet") 239 | var person = Person() 240 | let new = Pet(name: "Rex", age: 9) 241 | try pet.set(value: new, on: &person) 242 | XCTAssert(person.pet.name == "Rex") 243 | } 244 | 245 | func testSetStructUntypedValue() throws { 246 | let info = try typeInfo(of: Person.self) 247 | let pet = try info.property(named: "pet") 248 | var person = Person() 249 | let new = Pet(name: "Rex", age: 9) 250 | try pet.set(value: new, on: &person) 251 | XCTAssert(person.pet.name == "Rex") 252 | } 253 | 254 | func testSetStructUntypedObject() throws { 255 | let info = try typeInfo(of: Person.self) 256 | let pet = try info.property(named: "pet") 257 | var person: Any = Person() 258 | let new = Pet(name: "Rex", age: 9) 259 | try pet.set(value: new, on: &person) 260 | XCTAssert((person as! Person).pet.name == "Rex") 261 | } 262 | 263 | func testSetStructUntyped() throws { 264 | let info = try typeInfo(of: Person.self) 265 | let pet = try info.property(named: "pet") 266 | var person: Any = Person() 267 | let new = Pet(name: "Rex", age: 9) 268 | try pet.set(value: new, on: &person) 269 | XCTAssert((person as! Person).pet.name == "Rex") 270 | } 271 | 272 | func testSetCasting() throws { 273 | let info = try typeInfo(of: Person.self) 274 | let age = try info.property(named: "age") 275 | var person = Person() 276 | let newValue: NSNumber = 40 277 | try age.set(value: newValue, on: &person) 278 | XCTAssert(person.age == 40) 279 | } 280 | 281 | func testSetCastingFailure() throws { 282 | let info = try typeInfo(of: Person.self) 283 | let age = try info.property(named: "age") 284 | var person = Person() 285 | let newValue = "this will not work" 286 | try age.set(value: newValue, on: &person) 287 | XCTAssert(person.age == 25) 288 | } 289 | // swiftlint:enable force_cast 290 | } 291 | 292 | fileprivate struct Person { 293 | var firstname = "Wes" 294 | var lastname = "Wickwire" 295 | var age = 25 296 | var pet = Pet() 297 | var favoriteNumbers = [1, 2, 3, 4, 5] 298 | } 299 | 300 | fileprivate struct Pet { 301 | var name = "Marley" 302 | var age = 12 303 | init() {} 304 | init(name: String, age: Int) { 305 | self.name = name 306 | self.age = age 307 | } 308 | } 309 | // swiftlint:enable type_body_length 310 | -------------------------------------------------------------------------------- /Runtime.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = "1"; 4 | objectVersion = "46"; 5 | objects = { 6 | "OBJ_1" = { 7 | isa = "PBXProject"; 8 | attributes = { 9 | LastSwiftMigration = "9999"; 10 | LastUpgradeCheck = "9999"; 11 | }; 12 | buildConfigurationList = "OBJ_2"; 13 | compatibilityVersion = "Xcode 3.2"; 14 | developmentRegion = "en"; 15 | hasScannedForEncodings = "0"; 16 | knownRegions = ( 17 | "en" 18 | ); 19 | mainGroup = "OBJ_5"; 20 | productRefGroup = "OBJ_76"; 21 | projectDirPath = "."; 22 | targets = ( 23 | "Runtime::CRuntime", 24 | "Runtime::Runtime", 25 | "Runtime::SwiftPMPackageDescription", 26 | "Runtime::RuntimePackageTests::ProductTarget", 27 | "Runtime::RuntimeTests" 28 | ); 29 | }; 30 | "OBJ_10" = { 31 | isa = "PBXGroup"; 32 | children = ( 33 | "OBJ_11", 34 | "OBJ_12" 35 | ); 36 | name = "include"; 37 | path = "include"; 38 | sourceTree = ""; 39 | }; 40 | "OBJ_100" = { 41 | isa = "PBXBuildFile"; 42 | fileRef = "OBJ_19"; 43 | }; 44 | "OBJ_101" = { 45 | isa = "PBXBuildFile"; 46 | fileRef = "OBJ_20"; 47 | }; 48 | "OBJ_102" = { 49 | isa = "PBXBuildFile"; 50 | fileRef = "OBJ_21"; 51 | }; 52 | "OBJ_103" = { 53 | isa = "PBXBuildFile"; 54 | fileRef = "OBJ_22"; 55 | }; 56 | "OBJ_104" = { 57 | isa = "PBXBuildFile"; 58 | fileRef = "OBJ_23"; 59 | }; 60 | "OBJ_105" = { 61 | isa = "PBXBuildFile"; 62 | fileRef = "OBJ_24"; 63 | }; 64 | "OBJ_106" = { 65 | isa = "PBXBuildFile"; 66 | fileRef = "OBJ_25"; 67 | }; 68 | "OBJ_107" = { 69 | isa = "PBXBuildFile"; 70 | fileRef = "OBJ_26"; 71 | }; 72 | "OBJ_108" = { 73 | isa = "PBXBuildFile"; 74 | fileRef = "OBJ_27"; 75 | }; 76 | "OBJ_109" = { 77 | isa = "PBXBuildFile"; 78 | fileRef = "OBJ_28"; 79 | }; 80 | "OBJ_11" = { 81 | isa = "PBXFileReference"; 82 | path = "CRuntime.h"; 83 | sourceTree = ""; 84 | }; 85 | "OBJ_110" = { 86 | isa = "PBXBuildFile"; 87 | fileRef = "OBJ_29"; 88 | }; 89 | "OBJ_111" = { 90 | isa = "PBXBuildFile"; 91 | fileRef = "OBJ_30"; 92 | }; 93 | "OBJ_112" = { 94 | isa = "PBXBuildFile"; 95 | fileRef = "OBJ_31"; 96 | }; 97 | "OBJ_113" = { 98 | isa = "PBXBuildFile"; 99 | fileRef = "OBJ_32"; 100 | }; 101 | "OBJ_114" = { 102 | isa = "PBXBuildFile"; 103 | fileRef = "OBJ_33"; 104 | }; 105 | "OBJ_115" = { 106 | isa = "PBXBuildFile"; 107 | fileRef = "OBJ_34"; 108 | }; 109 | "OBJ_116" = { 110 | isa = "PBXBuildFile"; 111 | fileRef = "OBJ_35"; 112 | }; 113 | "OBJ_117" = { 114 | isa = "PBXBuildFile"; 115 | fileRef = "OBJ_36"; 116 | }; 117 | "OBJ_118" = { 118 | isa = "PBXBuildFile"; 119 | fileRef = "OBJ_38"; 120 | }; 121 | "OBJ_119" = { 122 | isa = "PBXBuildFile"; 123 | fileRef = "OBJ_39"; 124 | }; 125 | "OBJ_12" = { 126 | isa = "PBXFileReference"; 127 | name = "module.modulemap"; 128 | path = "/Users/wes/Projects/Runtime/Sources/CRuntime/include/module.modulemap"; 129 | sourceTree = ""; 130 | }; 131 | "OBJ_120" = { 132 | isa = "PBXBuildFile"; 133 | fileRef = "OBJ_40"; 134 | }; 135 | "OBJ_121" = { 136 | isa = "PBXBuildFile"; 137 | fileRef = "OBJ_41"; 138 | }; 139 | "OBJ_122" = { 140 | isa = "PBXBuildFile"; 141 | fileRef = "OBJ_42"; 142 | }; 143 | "OBJ_123" = { 144 | isa = "PBXBuildFile"; 145 | fileRef = "OBJ_43"; 146 | }; 147 | "OBJ_124" = { 148 | isa = "PBXBuildFile"; 149 | fileRef = "OBJ_44"; 150 | }; 151 | "OBJ_125" = { 152 | isa = "PBXBuildFile"; 153 | fileRef = "OBJ_45"; 154 | }; 155 | "OBJ_126" = { 156 | isa = "PBXBuildFile"; 157 | fileRef = "OBJ_46"; 158 | }; 159 | "OBJ_127" = { 160 | isa = "PBXBuildFile"; 161 | fileRef = "OBJ_48"; 162 | }; 163 | "OBJ_128" = { 164 | isa = "PBXBuildFile"; 165 | fileRef = "OBJ_49"; 166 | }; 167 | "OBJ_129" = { 168 | isa = "PBXBuildFile"; 169 | fileRef = "OBJ_50"; 170 | }; 171 | "OBJ_13" = { 172 | isa = "PBXGroup"; 173 | children = ( 174 | "OBJ_14", 175 | "OBJ_15", 176 | "OBJ_18", 177 | "OBJ_37", 178 | "OBJ_47", 179 | "OBJ_55", 180 | "OBJ_61" 181 | ); 182 | name = "Runtime"; 183 | path = "Sources/Runtime"; 184 | sourceTree = "SOURCE_ROOT"; 185 | }; 186 | "OBJ_130" = { 187 | isa = "PBXBuildFile"; 188 | fileRef = "OBJ_51"; 189 | }; 190 | "OBJ_131" = { 191 | isa = "PBXBuildFile"; 192 | fileRef = "OBJ_52"; 193 | }; 194 | "OBJ_132" = { 195 | isa = "PBXBuildFile"; 196 | fileRef = "OBJ_53"; 197 | }; 198 | "OBJ_133" = { 199 | isa = "PBXBuildFile"; 200 | fileRef = "OBJ_54"; 201 | }; 202 | "OBJ_134" = { 203 | isa = "PBXBuildFile"; 204 | fileRef = "OBJ_56"; 205 | }; 206 | "OBJ_135" = { 207 | isa = "PBXBuildFile"; 208 | fileRef = "OBJ_57"; 209 | }; 210 | "OBJ_136" = { 211 | isa = "PBXBuildFile"; 212 | fileRef = "OBJ_58"; 213 | }; 214 | "OBJ_137" = { 215 | isa = "PBXBuildFile"; 216 | fileRef = "OBJ_59"; 217 | }; 218 | "OBJ_138" = { 219 | isa = "PBXBuildFile"; 220 | fileRef = "OBJ_60"; 221 | }; 222 | "OBJ_139" = { 223 | isa = "PBXBuildFile"; 224 | fileRef = "OBJ_62"; 225 | }; 226 | "OBJ_14" = { 227 | isa = "PBXFileReference"; 228 | path = "Runtime.h"; 229 | sourceTree = ""; 230 | }; 231 | "OBJ_140" = { 232 | isa = "PBXBuildFile"; 233 | fileRef = "OBJ_63"; 234 | }; 235 | "OBJ_141" = { 236 | isa = "PBXBuildFile"; 237 | fileRef = "OBJ_64"; 238 | }; 239 | "OBJ_142" = { 240 | isa = "PBXBuildFile"; 241 | fileRef = "OBJ_65"; 242 | }; 243 | "OBJ_143" = { 244 | isa = "PBXFrameworksBuildPhase"; 245 | files = ( 246 | "OBJ_144" 247 | ); 248 | }; 249 | "OBJ_144" = { 250 | isa = "PBXBuildFile"; 251 | fileRef = "Runtime::CRuntime::Product"; 252 | }; 253 | "OBJ_145" = { 254 | isa = "PBXTargetDependency"; 255 | target = "Runtime::CRuntime"; 256 | }; 257 | "OBJ_147" = { 258 | isa = "XCConfigurationList"; 259 | buildConfigurations = ( 260 | "OBJ_148", 261 | "OBJ_149" 262 | ); 263 | defaultConfigurationIsVisible = "0"; 264 | defaultConfigurationName = "Release"; 265 | }; 266 | "OBJ_148" = { 267 | isa = "XCBuildConfiguration"; 268 | buildSettings = { 269 | LD = "/usr/bin/true"; 270 | OTHER_SWIFT_FLAGS = ( 271 | "-swift-version", 272 | "5", 273 | "-I", 274 | "$(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2", 275 | "-target", 276 | "x86_64-apple-macosx10.10", 277 | "-sdk", 278 | "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk", 279 | "-package-description-version", 280 | "5" 281 | ); 282 | SWIFT_VERSION = "5.0"; 283 | }; 284 | name = "Debug"; 285 | }; 286 | "OBJ_149" = { 287 | isa = "XCBuildConfiguration"; 288 | buildSettings = { 289 | LD = "/usr/bin/true"; 290 | OTHER_SWIFT_FLAGS = ( 291 | "-swift-version", 292 | "5", 293 | "-I", 294 | "$(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2", 295 | "-target", 296 | "x86_64-apple-macosx10.10", 297 | "-sdk", 298 | "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk", 299 | "-package-description-version", 300 | "5" 301 | ); 302 | SWIFT_VERSION = "5.0"; 303 | }; 304 | name = "Release"; 305 | }; 306 | "OBJ_15" = { 307 | isa = "PBXGroup"; 308 | children = ( 309 | "OBJ_16", 310 | "OBJ_17" 311 | ); 312 | name = "Factory"; 313 | path = "Factory"; 314 | sourceTree = ""; 315 | }; 316 | "OBJ_150" = { 317 | isa = "PBXSourcesBuildPhase"; 318 | files = ( 319 | "OBJ_151" 320 | ); 321 | }; 322 | "OBJ_151" = { 323 | isa = "PBXBuildFile"; 324 | fileRef = "OBJ_6"; 325 | }; 326 | "OBJ_153" = { 327 | isa = "XCConfigurationList"; 328 | buildConfigurations = ( 329 | "OBJ_154", 330 | "OBJ_155" 331 | ); 332 | defaultConfigurationIsVisible = "0"; 333 | defaultConfigurationName = "Release"; 334 | }; 335 | "OBJ_154" = { 336 | isa = "XCBuildConfiguration"; 337 | buildSettings = { 338 | }; 339 | name = "Debug"; 340 | }; 341 | "OBJ_155" = { 342 | isa = "XCBuildConfiguration"; 343 | buildSettings = { 344 | }; 345 | name = "Release"; 346 | }; 347 | "OBJ_156" = { 348 | isa = "PBXTargetDependency"; 349 | target = "Runtime::RuntimeTests"; 350 | }; 351 | "OBJ_158" = { 352 | isa = "XCConfigurationList"; 353 | buildConfigurations = ( 354 | "OBJ_159", 355 | "OBJ_160" 356 | ); 357 | defaultConfigurationIsVisible = "0"; 358 | defaultConfigurationName = "Release"; 359 | }; 360 | "OBJ_159" = { 361 | isa = "XCBuildConfiguration"; 362 | buildSettings = { 363 | CLANG_ENABLE_MODULES = "YES"; 364 | EMBEDDED_CONTENT_CONTAINS_SWIFT = "YES"; 365 | FRAMEWORK_SEARCH_PATHS = ( 366 | "$(inherited)", 367 | "$(PLATFORM_DIR)/Developer/Library/Frameworks" 368 | ); 369 | HEADER_SEARCH_PATHS = ( 370 | "$(inherited)", 371 | "$(SRCROOT)/Sources/CRuntime/include" 372 | ); 373 | INFOPLIST_FILE = "Runtime.xcodeproj/RuntimeTests_Info.plist"; 374 | IPHONEOS_DEPLOYMENT_TARGET = "8.0"; 375 | LD_RUNPATH_SEARCH_PATHS = ( 376 | "$(inherited)", 377 | "@loader_path/../Frameworks", 378 | "@loader_path/Frameworks" 379 | ); 380 | MACOSX_DEPLOYMENT_TARGET = "10.10"; 381 | OTHER_CFLAGS = ( 382 | "$(inherited)" 383 | ); 384 | OTHER_LDFLAGS = ( 385 | "$(inherited)" 386 | ); 387 | OTHER_SWIFT_FLAGS = ( 388 | "$(inherited)", 389 | "-Xcc", 390 | "-fmodule-map-file=$(SRCROOT)/Sources/CRuntime/include/module.modulemap" 391 | ); 392 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( 393 | "$(inherited)" 394 | ); 395 | SWIFT_VERSION = "5.0"; 396 | TARGET_NAME = "RuntimeTests"; 397 | TVOS_DEPLOYMENT_TARGET = "9.0"; 398 | WATCHOS_DEPLOYMENT_TARGET = "2.0"; 399 | }; 400 | name = "Debug"; 401 | }; 402 | "OBJ_16" = { 403 | isa = "PBXFileReference"; 404 | path = "DefaultValue.swift"; 405 | sourceTree = ""; 406 | }; 407 | "OBJ_160" = { 408 | isa = "XCBuildConfiguration"; 409 | buildSettings = { 410 | CLANG_ENABLE_MODULES = "YES"; 411 | EMBEDDED_CONTENT_CONTAINS_SWIFT = "YES"; 412 | FRAMEWORK_SEARCH_PATHS = ( 413 | "$(inherited)", 414 | "$(PLATFORM_DIR)/Developer/Library/Frameworks" 415 | ); 416 | HEADER_SEARCH_PATHS = ( 417 | "$(inherited)", 418 | "$(SRCROOT)/Sources/CRuntime/include" 419 | ); 420 | INFOPLIST_FILE = "Runtime.xcodeproj/RuntimeTests_Info.plist"; 421 | IPHONEOS_DEPLOYMENT_TARGET = "8.0"; 422 | LD_RUNPATH_SEARCH_PATHS = ( 423 | "$(inherited)", 424 | "@loader_path/../Frameworks", 425 | "@loader_path/Frameworks" 426 | ); 427 | MACOSX_DEPLOYMENT_TARGET = "10.10"; 428 | OTHER_CFLAGS = ( 429 | "$(inherited)" 430 | ); 431 | OTHER_LDFLAGS = ( 432 | "$(inherited)" 433 | ); 434 | OTHER_SWIFT_FLAGS = ( 435 | "$(inherited)", 436 | "-Xcc", 437 | "-fmodule-map-file=$(SRCROOT)/Sources/CRuntime/include/module.modulemap" 438 | ); 439 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( 440 | "$(inherited)" 441 | ); 442 | SWIFT_VERSION = "5.0"; 443 | TARGET_NAME = "RuntimeTests"; 444 | TVOS_DEPLOYMENT_TARGET = "9.0"; 445 | WATCHOS_DEPLOYMENT_TARGET = "2.0"; 446 | }; 447 | name = "Release"; 448 | }; 449 | "OBJ_161" = { 450 | isa = "PBXSourcesBuildPhase"; 451 | files = ( 452 | "OBJ_162", 453 | "OBJ_163", 454 | "OBJ_164", 455 | "OBJ_165", 456 | "OBJ_166", 457 | "OBJ_167", 458 | "OBJ_168" 459 | ); 460 | }; 461 | "OBJ_162" = { 462 | isa = "PBXBuildFile"; 463 | fileRef = "OBJ_69"; 464 | }; 465 | "OBJ_163" = { 466 | isa = "PBXBuildFile"; 467 | fileRef = "OBJ_70"; 468 | }; 469 | "OBJ_164" = { 470 | isa = "PBXBuildFile"; 471 | fileRef = "OBJ_71"; 472 | }; 473 | "OBJ_165" = { 474 | isa = "PBXBuildFile"; 475 | fileRef = "OBJ_72"; 476 | }; 477 | "OBJ_166" = { 478 | isa = "PBXBuildFile"; 479 | fileRef = "OBJ_73"; 480 | }; 481 | "OBJ_167" = { 482 | isa = "PBXBuildFile"; 483 | fileRef = "OBJ_74"; 484 | }; 485 | "OBJ_168" = { 486 | isa = "PBXBuildFile"; 487 | fileRef = "OBJ_75"; 488 | }; 489 | "OBJ_169" = { 490 | isa = "PBXFrameworksBuildPhase"; 491 | files = ( 492 | "OBJ_170", 493 | "OBJ_171" 494 | ); 495 | }; 496 | "OBJ_17" = { 497 | isa = "PBXFileReference"; 498 | path = "Factory.swift"; 499 | sourceTree = ""; 500 | }; 501 | "OBJ_170" = { 502 | isa = "PBXBuildFile"; 503 | fileRef = "Runtime::Runtime::Product"; 504 | }; 505 | "OBJ_171" = { 506 | isa = "PBXBuildFile"; 507 | fileRef = "Runtime::CRuntime::Product"; 508 | }; 509 | "OBJ_172" = { 510 | isa = "PBXTargetDependency"; 511 | target = "Runtime::Runtime"; 512 | }; 513 | "OBJ_173" = { 514 | isa = "PBXTargetDependency"; 515 | target = "Runtime::CRuntime"; 516 | }; 517 | "OBJ_18" = { 518 | isa = "PBXGroup"; 519 | children = ( 520 | "OBJ_19", 521 | "OBJ_20", 522 | "OBJ_21", 523 | "OBJ_22", 524 | "OBJ_23", 525 | "OBJ_24", 526 | "OBJ_25", 527 | "OBJ_26", 528 | "OBJ_27", 529 | "OBJ_28", 530 | "OBJ_29", 531 | "OBJ_30", 532 | "OBJ_31", 533 | "OBJ_32", 534 | "OBJ_33", 535 | "OBJ_34", 536 | "OBJ_35", 537 | "OBJ_36" 538 | ); 539 | name = "Layouts"; 540 | path = "Layouts"; 541 | sourceTree = ""; 542 | }; 543 | "OBJ_19" = { 544 | isa = "PBXFileReference"; 545 | path = "ClassHeader.swift"; 546 | sourceTree = ""; 547 | }; 548 | "OBJ_2" = { 549 | isa = "XCConfigurationList"; 550 | buildConfigurations = ( 551 | "OBJ_3", 552 | "OBJ_4" 553 | ); 554 | defaultConfigurationIsVisible = "0"; 555 | defaultConfigurationName = "Release"; 556 | }; 557 | "OBJ_20" = { 558 | isa = "PBXFileReference"; 559 | path = "ClassMetadataLayout.swift"; 560 | sourceTree = ""; 561 | }; 562 | "OBJ_21" = { 563 | isa = "PBXFileReference"; 564 | path = "ClassTypeDescriptor.swift"; 565 | sourceTree = ""; 566 | }; 567 | "OBJ_22" = { 568 | isa = "PBXFileReference"; 569 | path = "EnumMetadataLayout.swift"; 570 | sourceTree = ""; 571 | }; 572 | "OBJ_23" = { 573 | isa = "PBXFileReference"; 574 | path = "EnumTypeDescriptor.swift"; 575 | sourceTree = ""; 576 | }; 577 | "OBJ_24" = { 578 | isa = "PBXFileReference"; 579 | path = "ExistentialContainter.swift"; 580 | sourceTree = ""; 581 | }; 582 | "OBJ_25" = { 583 | isa = "PBXFileReference"; 584 | path = "FieldDescriptor.swift"; 585 | sourceTree = ""; 586 | }; 587 | "OBJ_26" = { 588 | isa = "PBXFileReference"; 589 | path = "FunctionMetadataLayout.swift"; 590 | sourceTree = ""; 591 | }; 592 | "OBJ_27" = { 593 | isa = "PBXFileReference"; 594 | path = "MetadataLayoutType.swift"; 595 | sourceTree = ""; 596 | }; 597 | "OBJ_28" = { 598 | isa = "PBXFileReference"; 599 | path = "ProtocolDescriptor.swift"; 600 | sourceTree = ""; 601 | }; 602 | "OBJ_29" = { 603 | isa = "PBXFileReference"; 604 | path = "ProtocolMetadataLayout.swift"; 605 | sourceTree = ""; 606 | }; 607 | "OBJ_3" = { 608 | isa = "XCBuildConfiguration"; 609 | buildSettings = { 610 | CLANG_ENABLE_OBJC_ARC = "YES"; 611 | COMBINE_HIDPI_IMAGES = "YES"; 612 | COPY_PHASE_STRIP = "NO"; 613 | DEBUG_INFORMATION_FORMAT = "dwarf"; 614 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 615 | ENABLE_NS_ASSERTIONS = "YES"; 616 | GCC_OPTIMIZATION_LEVEL = "0"; 617 | GCC_PREPROCESSOR_DEFINITIONS = ( 618 | "$(inherited)", 619 | "SWIFT_PACKAGE=1", 620 | "DEBUG=1" 621 | ); 622 | MACOSX_DEPLOYMENT_TARGET = "10.10"; 623 | ONLY_ACTIVE_ARCH = "YES"; 624 | OTHER_SWIFT_FLAGS = ( 625 | "$(inherited)", 626 | "-DXcode" 627 | ); 628 | PRODUCT_NAME = "$(TARGET_NAME)"; 629 | SDKROOT = "macosx"; 630 | SUPPORTED_PLATFORMS = ( 631 | "macosx", 632 | "iphoneos", 633 | "iphonesimulator", 634 | "appletvos", 635 | "appletvsimulator", 636 | "watchos", 637 | "watchsimulator" 638 | ); 639 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( 640 | "$(inherited)", 641 | "SWIFT_PACKAGE", 642 | "DEBUG" 643 | ); 644 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 645 | USE_HEADERMAP = "NO"; 646 | }; 647 | name = "Debug"; 648 | }; 649 | "OBJ_30" = { 650 | isa = "PBXFileReference"; 651 | path = "ProtocolTypeContainer.swift"; 652 | sourceTree = ""; 653 | }; 654 | "OBJ_31" = { 655 | isa = "PBXFileReference"; 656 | path = "StructMetadataLayout.swift"; 657 | sourceTree = ""; 658 | }; 659 | "OBJ_32" = { 660 | isa = "PBXFileReference"; 661 | path = "StructTypeDescriptor.swift"; 662 | sourceTree = ""; 663 | }; 664 | "OBJ_33" = { 665 | isa = "PBXFileReference"; 666 | path = "TargetTypeGenericContextDescriptorHeader.swift"; 667 | sourceTree = ""; 668 | }; 669 | "OBJ_34" = { 670 | isa = "PBXFileReference"; 671 | path = "TupleMetadataLayout.swift"; 672 | sourceTree = ""; 673 | }; 674 | "OBJ_35" = { 675 | isa = "PBXFileReference"; 676 | path = "TypeDescriptor.swift"; 677 | sourceTree = ""; 678 | }; 679 | "OBJ_36" = { 680 | isa = "PBXFileReference"; 681 | path = "ValueWitnessTable.swift"; 682 | sourceTree = ""; 683 | }; 684 | "OBJ_37" = { 685 | isa = "PBXGroup"; 686 | children = ( 687 | "OBJ_38", 688 | "OBJ_39", 689 | "OBJ_40", 690 | "OBJ_41", 691 | "OBJ_42", 692 | "OBJ_43", 693 | "OBJ_44", 694 | "OBJ_45", 695 | "OBJ_46" 696 | ); 697 | name = "Metadata"; 698 | path = "Metadata"; 699 | sourceTree = ""; 700 | }; 701 | "OBJ_38" = { 702 | isa = "PBXFileReference"; 703 | path = "ClassMetadata.swift"; 704 | sourceTree = ""; 705 | }; 706 | "OBJ_39" = { 707 | isa = "PBXFileReference"; 708 | path = "EnumMetadata.swift"; 709 | sourceTree = ""; 710 | }; 711 | "OBJ_4" = { 712 | isa = "XCBuildConfiguration"; 713 | buildSettings = { 714 | CLANG_ENABLE_OBJC_ARC = "YES"; 715 | COMBINE_HIDPI_IMAGES = "YES"; 716 | COPY_PHASE_STRIP = "YES"; 717 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 718 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 719 | GCC_OPTIMIZATION_LEVEL = "s"; 720 | GCC_PREPROCESSOR_DEFINITIONS = ( 721 | "$(inherited)", 722 | "SWIFT_PACKAGE=1" 723 | ); 724 | MACOSX_DEPLOYMENT_TARGET = "10.10"; 725 | OTHER_SWIFT_FLAGS = ( 726 | "$(inherited)", 727 | "-DXcode" 728 | ); 729 | PRODUCT_NAME = "$(TARGET_NAME)"; 730 | SDKROOT = "macosx"; 731 | SUPPORTED_PLATFORMS = ( 732 | "macosx", 733 | "iphoneos", 734 | "iphonesimulator", 735 | "appletvos", 736 | "appletvsimulator", 737 | "watchos", 738 | "watchsimulator" 739 | ); 740 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( 741 | "$(inherited)", 742 | "SWIFT_PACKAGE" 743 | ); 744 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 745 | USE_HEADERMAP = "NO"; 746 | }; 747 | name = "Release"; 748 | }; 749 | "OBJ_40" = { 750 | isa = "PBXFileReference"; 751 | path = "FuntionMetadata.swift"; 752 | sourceTree = ""; 753 | }; 754 | "OBJ_41" = { 755 | isa = "PBXFileReference"; 756 | path = "Metadata.swift"; 757 | sourceTree = ""; 758 | }; 759 | "OBJ_42" = { 760 | isa = "PBXFileReference"; 761 | path = "MetadataType.swift"; 762 | sourceTree = ""; 763 | }; 764 | "OBJ_43" = { 765 | isa = "PBXFileReference"; 766 | path = "NominalMetadataType.swift"; 767 | sourceTree = ""; 768 | }; 769 | "OBJ_44" = { 770 | isa = "PBXFileReference"; 771 | path = "ProtocolMetadata.swift"; 772 | sourceTree = ""; 773 | }; 774 | "OBJ_45" = { 775 | isa = "PBXFileReference"; 776 | path = "StructMetadata.swift"; 777 | sourceTree = ""; 778 | }; 779 | "OBJ_46" = { 780 | isa = "PBXFileReference"; 781 | path = "TupleMetadata.swift"; 782 | sourceTree = ""; 783 | }; 784 | "OBJ_47" = { 785 | isa = "PBXGroup"; 786 | children = ( 787 | "OBJ_48", 788 | "OBJ_49", 789 | "OBJ_50", 790 | "OBJ_51", 791 | "OBJ_52", 792 | "OBJ_53", 793 | "OBJ_54" 794 | ); 795 | name = "Models"; 796 | path = "Models"; 797 | sourceTree = ""; 798 | }; 799 | "OBJ_48" = { 800 | isa = "PBXFileReference"; 801 | path = "Case.swift"; 802 | sourceTree = ""; 803 | }; 804 | "OBJ_49" = { 805 | isa = "PBXFileReference"; 806 | path = "Errors.swift"; 807 | sourceTree = ""; 808 | }; 809 | "OBJ_5" = { 810 | isa = "PBXGroup"; 811 | children = ( 812 | "OBJ_6", 813 | "OBJ_7", 814 | "OBJ_66", 815 | "OBJ_76", 816 | "OBJ_80", 817 | "OBJ_81", 818 | "OBJ_82", 819 | "OBJ_83", 820 | "OBJ_84", 821 | "OBJ_85" 822 | ); 823 | path = ""; 824 | sourceTree = ""; 825 | }; 826 | "OBJ_50" = { 827 | isa = "PBXFileReference"; 828 | path = "FunctionInfo.swift"; 829 | sourceTree = ""; 830 | }; 831 | "OBJ_51" = { 832 | isa = "PBXFileReference"; 833 | path = "Kind.swift"; 834 | sourceTree = ""; 835 | }; 836 | "OBJ_52" = { 837 | isa = "PBXFileReference"; 838 | path = "PropertyInfo.swift"; 839 | sourceTree = ""; 840 | }; 841 | "OBJ_53" = { 842 | isa = "PBXFileReference"; 843 | path = "TypeInfo.swift"; 844 | sourceTree = ""; 845 | }; 846 | "OBJ_54" = { 847 | isa = "PBXFileReference"; 848 | path = "TypeInfoConvertible.swift"; 849 | sourceTree = ""; 850 | }; 851 | "OBJ_55" = { 852 | isa = "PBXGroup"; 853 | children = ( 854 | "OBJ_56", 855 | "OBJ_57", 856 | "OBJ_58", 857 | "OBJ_59", 858 | "OBJ_60" 859 | ); 860 | name = "Pointers"; 861 | path = "Pointers"; 862 | sourceTree = ""; 863 | }; 864 | "OBJ_56" = { 865 | isa = "PBXFileReference"; 866 | path = "Pointers.swift"; 867 | sourceTree = ""; 868 | }; 869 | "OBJ_57" = { 870 | isa = "PBXFileReference"; 871 | path = "RelativePointer.swift"; 872 | sourceTree = ""; 873 | }; 874 | "OBJ_58" = { 875 | isa = "PBXFileReference"; 876 | path = "RelativeVectorPointer.swift"; 877 | sourceTree = ""; 878 | }; 879 | "OBJ_59" = { 880 | isa = "PBXFileReference"; 881 | path = "Union.swift"; 882 | sourceTree = ""; 883 | }; 884 | "OBJ_6" = { 885 | isa = "PBXFileReference"; 886 | explicitFileType = "sourcecode.swift"; 887 | path = "Package.swift"; 888 | sourceTree = ""; 889 | }; 890 | "OBJ_60" = { 891 | isa = "PBXFileReference"; 892 | path = "Vector.swift"; 893 | sourceTree = ""; 894 | }; 895 | "OBJ_61" = { 896 | isa = "PBXGroup"; 897 | children = ( 898 | "OBJ_62", 899 | "OBJ_63", 900 | "OBJ_64", 901 | "OBJ_65" 902 | ); 903 | name = "Utilities"; 904 | path = "Utilities"; 905 | sourceTree = ""; 906 | }; 907 | "OBJ_62" = { 908 | isa = "PBXFileReference"; 909 | path = "GettersSetters.swift"; 910 | sourceTree = ""; 911 | }; 912 | "OBJ_63" = { 913 | isa = "PBXFileReference"; 914 | path = "Pointer+Extensions.swift"; 915 | sourceTree = ""; 916 | }; 917 | "OBJ_64" = { 918 | isa = "PBXFileReference"; 919 | path = "RetainCounts.swift"; 920 | sourceTree = ""; 921 | }; 922 | "OBJ_65" = { 923 | isa = "PBXFileReference"; 924 | path = "String+Extensions.swift"; 925 | sourceTree = ""; 926 | }; 927 | "OBJ_66" = { 928 | isa = "PBXGroup"; 929 | children = ( 930 | "OBJ_67" 931 | ); 932 | name = "Tests"; 933 | path = ""; 934 | sourceTree = "SOURCE_ROOT"; 935 | }; 936 | "OBJ_67" = { 937 | isa = "PBXGroup"; 938 | children = ( 939 | "OBJ_68", 940 | "OBJ_69", 941 | "OBJ_70", 942 | "OBJ_71", 943 | "OBJ_72", 944 | "OBJ_73", 945 | "OBJ_74", 946 | "OBJ_75" 947 | ); 948 | name = "RuntimeTests"; 949 | path = "Tests/RuntimeTests"; 950 | sourceTree = "SOURCE_ROOT"; 951 | }; 952 | "OBJ_68" = { 953 | isa = "PBXFileReference"; 954 | path = "Info.plist"; 955 | sourceTree = ""; 956 | }; 957 | "OBJ_69" = { 958 | isa = "PBXFileReference"; 959 | path = "FactoryTests.swift"; 960 | sourceTree = ""; 961 | }; 962 | "OBJ_7" = { 963 | isa = "PBXGroup"; 964 | children = ( 965 | "OBJ_8", 966 | "OBJ_13" 967 | ); 968 | name = "Sources"; 969 | path = ""; 970 | sourceTree = "SOURCE_ROOT"; 971 | }; 972 | "OBJ_70" = { 973 | isa = "PBXFileReference"; 974 | path = "GetSetClassTests.swift"; 975 | sourceTree = ""; 976 | }; 977 | "OBJ_71" = { 978 | isa = "PBXFileReference"; 979 | path = "GetSetStructTests.swift"; 980 | sourceTree = ""; 981 | }; 982 | "OBJ_72" = { 983 | isa = "PBXFileReference"; 984 | path = "MetadataTests.swift"; 985 | sourceTree = ""; 986 | }; 987 | "OBJ_73" = { 988 | isa = "PBXFileReference"; 989 | path = "ValuePointerTests.swift"; 990 | sourceTree = ""; 991 | }; 992 | "OBJ_74" = { 993 | isa = "PBXFileReference"; 994 | path = "ValueWitnessTableTests.swift"; 995 | sourceTree = ""; 996 | }; 997 | "OBJ_75" = { 998 | isa = "PBXFileReference"; 999 | path = "XCTestManifests.swift"; 1000 | sourceTree = ""; 1001 | }; 1002 | "OBJ_76" = { 1003 | isa = "PBXGroup"; 1004 | children = ( 1005 | "Runtime::CRuntime::Product", 1006 | "Runtime::RuntimeTests::Product", 1007 | "Runtime::Runtime::Product" 1008 | ); 1009 | name = "Products"; 1010 | path = ""; 1011 | sourceTree = "BUILT_PRODUCTS_DIR"; 1012 | }; 1013 | "OBJ_8" = { 1014 | isa = "PBXGroup"; 1015 | children = ( 1016 | "OBJ_9", 1017 | "OBJ_10" 1018 | ); 1019 | name = "CRuntime"; 1020 | path = "Sources/CRuntime"; 1021 | sourceTree = "SOURCE_ROOT"; 1022 | }; 1023 | "OBJ_80" = { 1024 | isa = "PBXFileReference"; 1025 | path = "Resources"; 1026 | sourceTree = "SOURCE_ROOT"; 1027 | }; 1028 | "OBJ_81" = { 1029 | isa = "PBXFileReference"; 1030 | path = "Scripts"; 1031 | sourceTree = "SOURCE_ROOT"; 1032 | }; 1033 | "OBJ_82" = { 1034 | isa = "PBXFileReference"; 1035 | path = "LICENSE"; 1036 | sourceTree = ""; 1037 | }; 1038 | "OBJ_83" = { 1039 | isa = "PBXFileReference"; 1040 | path = "README.md"; 1041 | sourceTree = ""; 1042 | }; 1043 | "OBJ_84" = { 1044 | isa = "PBXFileReference"; 1045 | path = "Podfile"; 1046 | sourceTree = ""; 1047 | }; 1048 | "OBJ_85" = { 1049 | isa = "PBXFileReference"; 1050 | path = "Runtime.podspec"; 1051 | sourceTree = ""; 1052 | }; 1053 | "OBJ_87" = { 1054 | isa = "XCConfigurationList"; 1055 | buildConfigurations = ( 1056 | "OBJ_88", 1057 | "OBJ_89" 1058 | ); 1059 | defaultConfigurationIsVisible = "0"; 1060 | defaultConfigurationName = "Release"; 1061 | }; 1062 | "OBJ_88" = { 1063 | isa = "XCBuildConfiguration"; 1064 | buildSettings = { 1065 | DEFINES_MODULE = "NO"; 1066 | ENABLE_TESTABILITY = "YES"; 1067 | FRAMEWORK_SEARCH_PATHS = ( 1068 | "$(inherited)", 1069 | "$(PLATFORM_DIR)/Developer/Library/Frameworks" 1070 | ); 1071 | HEADER_SEARCH_PATHS = ( 1072 | "$(inherited)", 1073 | "$(SRCROOT)/Sources/CRuntime/include" 1074 | ); 1075 | INFOPLIST_FILE = "Runtime.xcodeproj/CRuntime_Info.plist"; 1076 | IPHONEOS_DEPLOYMENT_TARGET = "8.0"; 1077 | LD_RUNPATH_SEARCH_PATHS = ( 1078 | "$(inherited)", 1079 | "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx" 1080 | ); 1081 | MACOSX_DEPLOYMENT_TARGET = "10.10"; 1082 | OTHER_CFLAGS = ( 1083 | "$(inherited)" 1084 | ); 1085 | OTHER_LDFLAGS = ( 1086 | "$(inherited)" 1087 | ); 1088 | OTHER_SWIFT_FLAGS = ( 1089 | "$(inherited)" 1090 | ); 1091 | PRODUCT_BUNDLE_IDENTIFIER = "CRuntime"; 1092 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 1093 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 1094 | SKIP_INSTALL = "YES"; 1095 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( 1096 | "$(inherited)" 1097 | ); 1098 | TARGET_NAME = "CRuntime"; 1099 | TVOS_DEPLOYMENT_TARGET = "9.0"; 1100 | WATCHOS_DEPLOYMENT_TARGET = "2.0"; 1101 | }; 1102 | name = "Debug"; 1103 | }; 1104 | "OBJ_89" = { 1105 | isa = "XCBuildConfiguration"; 1106 | buildSettings = { 1107 | DEFINES_MODULE = "NO"; 1108 | ENABLE_TESTABILITY = "YES"; 1109 | FRAMEWORK_SEARCH_PATHS = ( 1110 | "$(inherited)", 1111 | "$(PLATFORM_DIR)/Developer/Library/Frameworks" 1112 | ); 1113 | HEADER_SEARCH_PATHS = ( 1114 | "$(inherited)", 1115 | "$(SRCROOT)/Sources/CRuntime/include" 1116 | ); 1117 | INFOPLIST_FILE = "Runtime.xcodeproj/CRuntime_Info.plist"; 1118 | IPHONEOS_DEPLOYMENT_TARGET = "8.0"; 1119 | LD_RUNPATH_SEARCH_PATHS = ( 1120 | "$(inherited)", 1121 | "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx" 1122 | ); 1123 | MACOSX_DEPLOYMENT_TARGET = "10.10"; 1124 | OTHER_CFLAGS = ( 1125 | "$(inherited)" 1126 | ); 1127 | OTHER_LDFLAGS = ( 1128 | "$(inherited)" 1129 | ); 1130 | OTHER_SWIFT_FLAGS = ( 1131 | "$(inherited)" 1132 | ); 1133 | PRODUCT_BUNDLE_IDENTIFIER = "CRuntime"; 1134 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 1135 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 1136 | SKIP_INSTALL = "YES"; 1137 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( 1138 | "$(inherited)" 1139 | ); 1140 | TARGET_NAME = "CRuntime"; 1141 | TVOS_DEPLOYMENT_TARGET = "9.0"; 1142 | WATCHOS_DEPLOYMENT_TARGET = "2.0"; 1143 | }; 1144 | name = "Release"; 1145 | }; 1146 | "OBJ_9" = { 1147 | isa = "PBXFileReference"; 1148 | path = "dummy.c"; 1149 | sourceTree = ""; 1150 | }; 1151 | "OBJ_90" = { 1152 | isa = "PBXSourcesBuildPhase"; 1153 | files = ( 1154 | "OBJ_91" 1155 | ); 1156 | }; 1157 | "OBJ_91" = { 1158 | isa = "PBXBuildFile"; 1159 | fileRef = "OBJ_9"; 1160 | }; 1161 | "OBJ_92" = { 1162 | isa = "PBXFrameworksBuildPhase"; 1163 | files = ( 1164 | ); 1165 | }; 1166 | "OBJ_94" = { 1167 | isa = "XCConfigurationList"; 1168 | buildConfigurations = ( 1169 | "OBJ_95", 1170 | "OBJ_96" 1171 | ); 1172 | defaultConfigurationIsVisible = "0"; 1173 | defaultConfigurationName = "Release"; 1174 | }; 1175 | "OBJ_95" = { 1176 | isa = "XCBuildConfiguration"; 1177 | buildSettings = { 1178 | ENABLE_TESTABILITY = "YES"; 1179 | FRAMEWORK_SEARCH_PATHS = ( 1180 | "$(inherited)", 1181 | "$(PLATFORM_DIR)/Developer/Library/Frameworks" 1182 | ); 1183 | HEADER_SEARCH_PATHS = ( 1184 | "$(inherited)", 1185 | "$(SRCROOT)/Sources/CRuntime/include" 1186 | ); 1187 | INFOPLIST_FILE = "Runtime.xcodeproj/Runtime_Info.plist"; 1188 | IPHONEOS_DEPLOYMENT_TARGET = "8.0"; 1189 | LD_RUNPATH_SEARCH_PATHS = ( 1190 | "$(inherited)", 1191 | "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx" 1192 | ); 1193 | MACOSX_DEPLOYMENT_TARGET = "10.10"; 1194 | OTHER_CFLAGS = ( 1195 | "$(inherited)" 1196 | ); 1197 | OTHER_LDFLAGS = ( 1198 | "$(inherited)" 1199 | ); 1200 | OTHER_SWIFT_FLAGS = ( 1201 | "$(inherited)", 1202 | "-Xcc", 1203 | "-fmodule-map-file=$(SRCROOT)/Sources/CRuntime/include/module.modulemap" 1204 | ); 1205 | PRODUCT_BUNDLE_IDENTIFIER = "Runtime"; 1206 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 1207 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 1208 | SKIP_INSTALL = "YES"; 1209 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( 1210 | "$(inherited)" 1211 | ); 1212 | SWIFT_VERSION = "5.0"; 1213 | TARGET_NAME = "Runtime"; 1214 | TVOS_DEPLOYMENT_TARGET = "9.0"; 1215 | WATCHOS_DEPLOYMENT_TARGET = "2.0"; 1216 | }; 1217 | name = "Debug"; 1218 | }; 1219 | "OBJ_96" = { 1220 | isa = "XCBuildConfiguration"; 1221 | buildSettings = { 1222 | ENABLE_TESTABILITY = "YES"; 1223 | FRAMEWORK_SEARCH_PATHS = ( 1224 | "$(inherited)", 1225 | "$(PLATFORM_DIR)/Developer/Library/Frameworks" 1226 | ); 1227 | HEADER_SEARCH_PATHS = ( 1228 | "$(inherited)", 1229 | "$(SRCROOT)/Sources/CRuntime/include" 1230 | ); 1231 | INFOPLIST_FILE = "Runtime.xcodeproj/Runtime_Info.plist"; 1232 | IPHONEOS_DEPLOYMENT_TARGET = "8.0"; 1233 | LD_RUNPATH_SEARCH_PATHS = ( 1234 | "$(inherited)", 1235 | "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx" 1236 | ); 1237 | MACOSX_DEPLOYMENT_TARGET = "10.10"; 1238 | OTHER_CFLAGS = ( 1239 | "$(inherited)" 1240 | ); 1241 | OTHER_LDFLAGS = ( 1242 | "$(inherited)" 1243 | ); 1244 | OTHER_SWIFT_FLAGS = ( 1245 | "$(inherited)", 1246 | "-Xcc", 1247 | "-fmodule-map-file=$(SRCROOT)/Sources/CRuntime/include/module.modulemap" 1248 | ); 1249 | PRODUCT_BUNDLE_IDENTIFIER = "Runtime"; 1250 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; 1251 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 1252 | SKIP_INSTALL = "YES"; 1253 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = ( 1254 | "$(inherited)" 1255 | ); 1256 | SWIFT_VERSION = "5.0"; 1257 | TARGET_NAME = "Runtime"; 1258 | TVOS_DEPLOYMENT_TARGET = "9.0"; 1259 | WATCHOS_DEPLOYMENT_TARGET = "2.0"; 1260 | }; 1261 | name = "Release"; 1262 | }; 1263 | "OBJ_97" = { 1264 | isa = "PBXSourcesBuildPhase"; 1265 | files = ( 1266 | "OBJ_98", 1267 | "OBJ_99", 1268 | "OBJ_100", 1269 | "OBJ_101", 1270 | "OBJ_102", 1271 | "OBJ_103", 1272 | "OBJ_104", 1273 | "OBJ_105", 1274 | "OBJ_106", 1275 | "OBJ_107", 1276 | "OBJ_108", 1277 | "OBJ_109", 1278 | "OBJ_110", 1279 | "OBJ_111", 1280 | "OBJ_112", 1281 | "OBJ_113", 1282 | "OBJ_114", 1283 | "OBJ_115", 1284 | "OBJ_116", 1285 | "OBJ_117", 1286 | "OBJ_118", 1287 | "OBJ_119", 1288 | "OBJ_120", 1289 | "OBJ_121", 1290 | "OBJ_122", 1291 | "OBJ_123", 1292 | "OBJ_124", 1293 | "OBJ_125", 1294 | "OBJ_126", 1295 | "OBJ_127", 1296 | "OBJ_128", 1297 | "OBJ_129", 1298 | "OBJ_130", 1299 | "OBJ_131", 1300 | "OBJ_132", 1301 | "OBJ_133", 1302 | "OBJ_134", 1303 | "OBJ_135", 1304 | "OBJ_136", 1305 | "OBJ_137", 1306 | "OBJ_138", 1307 | "OBJ_139", 1308 | "OBJ_140", 1309 | "OBJ_141", 1310 | "OBJ_142" 1311 | ); 1312 | }; 1313 | "OBJ_98" = { 1314 | isa = "PBXBuildFile"; 1315 | fileRef = "OBJ_16"; 1316 | }; 1317 | "OBJ_99" = { 1318 | isa = "PBXBuildFile"; 1319 | fileRef = "OBJ_17"; 1320 | }; 1321 | "Runtime::CRuntime" = { 1322 | isa = "PBXNativeTarget"; 1323 | buildConfigurationList = "OBJ_87"; 1324 | buildPhases = ( 1325 | "OBJ_90", 1326 | "OBJ_92" 1327 | ); 1328 | dependencies = ( 1329 | ); 1330 | name = "CRuntime"; 1331 | productName = "CRuntime"; 1332 | productReference = "Runtime::CRuntime::Product"; 1333 | productType = "com.apple.product-type.framework"; 1334 | }; 1335 | "Runtime::CRuntime::Product" = { 1336 | isa = "PBXFileReference"; 1337 | path = "CRuntime.framework"; 1338 | sourceTree = "BUILT_PRODUCTS_DIR"; 1339 | }; 1340 | "Runtime::Runtime" = { 1341 | isa = "PBXNativeTarget"; 1342 | buildConfigurationList = "OBJ_94"; 1343 | buildPhases = ( 1344 | "OBJ_97", 1345 | "OBJ_143" 1346 | ); 1347 | dependencies = ( 1348 | "OBJ_145" 1349 | ); 1350 | name = "Runtime"; 1351 | productName = "Runtime"; 1352 | productReference = "Runtime::Runtime::Product"; 1353 | productType = "com.apple.product-type.framework"; 1354 | }; 1355 | "Runtime::Runtime::Product" = { 1356 | isa = "PBXFileReference"; 1357 | path = "Runtime.framework"; 1358 | sourceTree = "BUILT_PRODUCTS_DIR"; 1359 | }; 1360 | "Runtime::RuntimePackageTests::ProductTarget" = { 1361 | isa = "PBXAggregateTarget"; 1362 | buildConfigurationList = "OBJ_153"; 1363 | buildPhases = ( 1364 | ); 1365 | dependencies = ( 1366 | "OBJ_156" 1367 | ); 1368 | name = "RuntimePackageTests"; 1369 | productName = "RuntimePackageTests"; 1370 | }; 1371 | "Runtime::RuntimeTests" = { 1372 | isa = "PBXNativeTarget"; 1373 | buildConfigurationList = "OBJ_158"; 1374 | buildPhases = ( 1375 | "OBJ_161", 1376 | "OBJ_169" 1377 | ); 1378 | dependencies = ( 1379 | "OBJ_172", 1380 | "OBJ_173" 1381 | ); 1382 | name = "RuntimeTests"; 1383 | productName = "RuntimeTests"; 1384 | productReference = "Runtime::RuntimeTests::Product"; 1385 | productType = "com.apple.product-type.bundle.unit-test"; 1386 | }; 1387 | "Runtime::RuntimeTests::Product" = { 1388 | isa = "PBXFileReference"; 1389 | path = "RuntimeTests.xctest"; 1390 | sourceTree = "BUILT_PRODUCTS_DIR"; 1391 | }; 1392 | "Runtime::SwiftPMPackageDescription" = { 1393 | isa = "PBXNativeTarget"; 1394 | buildConfigurationList = "OBJ_147"; 1395 | buildPhases = ( 1396 | "OBJ_150" 1397 | ); 1398 | dependencies = ( 1399 | ); 1400 | name = "RuntimePackageDescription"; 1401 | productName = "RuntimePackageDescription"; 1402 | productType = "com.apple.product-type.framework"; 1403 | }; 1404 | }; 1405 | rootObject = "OBJ_1"; 1406 | } 1407 | --------------------------------------------------------------------------------