From 4a109af391a6bf6552c01b3e7ae2da858a151c18 Mon Sep 17 00:00:00 2001 From: Apple Date: Tue, 26 Sep 2017 16:55:53 +0000 Subject: [PATCH] objc4-723.tar.gz --- interposable.txt | 1 + markgc.cpp | 22 +- objc.xcodeproj/project.pbxproj | 52 +- runtime/Module/ObjectiveC.apinotes | 437 ++++++++++++++++ runtime/Module/module.modulemap | 40 ++ runtime/NSObject.h | 11 +- runtime/NSObject.mm | 18 +- runtime/Object.h | 3 +- runtime/Object.mm | 3 +- runtime/Protocol.h | 10 +- runtime/hashtable2.h | 147 ++++-- runtime/maptable.h | 82 ++- runtime/message.h | 149 +++--- runtime/objc-abi.h | 234 ++++++--- runtime/objc-api.h | 38 +- runtime/objc-auto.h | 70 ++- runtime/objc-block-trampolines.mm | 73 +-- runtime/objc-env.h | 1 + runtime/objc-exception.h | 128 +++-- runtime/objc-gdb.h | 72 +-- runtime/objc-initialize.mm | 171 ++++++- runtime/objc-internal.h | 425 +++++++++------- runtime/objc-load.h | 21 +- runtime/objc-lockdebug.h | 2 +- runtime/objc-lockdebug.mm | 47 +- runtime/objc-locks.h | 2 + runtime/objc-os.h | 105 ++-- runtime/objc-os.mm | 97 +++- runtime/objc-private.h | 15 +- runtime/objc-references.mm | 10 +- runtime/objc-runtime-new.mm | 13 +- runtime/objc-runtime-old.h | 8 + runtime/objc-runtime.mm | 13 + runtime/objc-sel-table.s | 29 +- runtime/objc-sync.h | 28 +- runtime/objc.h | 34 +- runtime/runtime.h | 775 ++++++++++++++++++----------- 37 files changed, 2339 insertions(+), 1047 deletions(-) create mode 100644 interposable.txt create mode 100644 runtime/Module/ObjectiveC.apinotes create mode 100644 runtime/Module/module.modulemap diff --git a/interposable.txt b/interposable.txt new file mode 100644 index 0000000..f5d09f3 --- /dev/null +++ b/interposable.txt @@ -0,0 +1 @@ +_objc_release diff --git a/markgc.cpp b/markgc.cpp index 49fd2ba..4543ad6 100644 --- a/markgc.cpp +++ b/markgc.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -476,7 +477,15 @@ bool parse_fat(uint8_t *buffer, size_t size) fat_magic = OSSwapBigToHostInt32(fh->magic); fat_nfat_arch = OSSwapBigToHostInt32(fh->nfat_arch); - if (size < (sizeof(struct fat_header) + fat_nfat_arch * sizeof(struct fat_arch))) { + size_t fat_arch_size; + // fat_nfat_arch * sizeof(struct fat_arch) + sizeof(struct fat_header) + if (os_mul_and_add_overflow(fat_nfat_arch, sizeof(struct fat_arch), + sizeof(struct fat_header), &fat_arch_size)) + { + printf("too many fat archs\n"); + return false; + } + if (size < fat_arch_size) { printf("file is too small\n"); return false; } @@ -484,7 +493,14 @@ bool parse_fat(uint8_t *buffer, size_t size) archs = (struct fat_arch *)(buffer + sizeof(struct fat_header)); /* Special case hidden CPU_TYPE_ARM64 */ - if (size >= (sizeof(struct fat_header) + (fat_nfat_arch + 1) * sizeof(struct fat_arch))) { + size_t fat_arch_plus_one_size; + if (os_add_overflow(fat_arch_size, sizeof(struct fat_arch), + &fat_arch_plus_one_size)) + { + printf("too many fat archs\n"); + return false; + } + if (size >= fat_arch_plus_one_size) { if (fat_nfat_arch > 0 && OSSwapBigToHostInt32(archs[fat_nfat_arch].cputype) == CPU_TYPE_ARM64) { fat_nfat_arch++; @@ -505,7 +521,7 @@ bool parse_fat(uint8_t *buffer, size_t size) arch_cputype, arch_cpusubtype); /* Check that slice data is after all fat headers and archs */ - if (arch_offset < (sizeof(struct fat_header) + fat_nfat_arch * sizeof(struct fat_arch))) { + if (arch_offset < fat_arch_size) { printf("file is badly formed\n"); return false; } diff --git a/objc.xcodeproj/project.pbxproj b/objc.xcodeproj/project.pbxproj index abf396d..1cd3e32 100644 --- a/objc.xcodeproj/project.pbxproj +++ b/objc.xcodeproj/project.pbxproj @@ -63,7 +63,7 @@ 838485FF0D6D68A200CEA253 /* objc-load.mm in Sources */ = {isa = PBXBuildFile; fileRef = 838485D80D6D68A200CEA253 /* objc-load.mm */; }; 838486000D6D68A200CEA253 /* objc-loadmethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 838485D90D6D68A200CEA253 /* objc-loadmethod.h */; }; 838486010D6D68A200CEA253 /* objc-loadmethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = 838485DA0D6D68A200CEA253 /* objc-loadmethod.mm */; }; - 838486020D6D68A200CEA253 /* objc-lockdebug.mm in Sources */ = {isa = PBXBuildFile; fileRef = 838485DB0D6D68A200CEA253 /* objc-lockdebug.mm */; }; + 838486020D6D68A200CEA253 /* objc-lockdebug.mm in Sources */ = {isa = PBXBuildFile; fileRef = 838485DB0D6D68A200CEA253 /* objc-lockdebug.mm */; settings = {COMPILER_FLAGS = "-Os"; }; }; 838486030D6D68A200CEA253 /* objc-private.h in Headers */ = {isa = PBXBuildFile; fileRef = 838485DC0D6D68A200CEA253 /* objc-private.h */; }; 838486070D6D68A200CEA253 /* objc-runtime-new.h in Headers */ = {isa = PBXBuildFile; fileRef = 838485E00D6D68A200CEA253 /* objc-runtime-new.h */; }; 838486080D6D68A200CEA253 /* objc-runtime-new.mm in Sources */ = {isa = PBXBuildFile; fileRef = 838485E10D6D68A200CEA253 /* objc-runtime-new.mm */; }; @@ -85,6 +85,8 @@ 838486250D6D68F000CEA253 /* List.m in Sources */ = {isa = PBXBuildFile; fileRef = 838486230D6D68F000CEA253 /* List.m */; }; 838486260D6D68F000CEA253 /* List.h in Headers */ = {isa = PBXBuildFile; fileRef = 838486240D6D68F000CEA253 /* List.h */; settings = {ATTRIBUTES = (Public, ); }; }; 838486280D6D6A2400CEA253 /* message.h in Headers */ = {isa = PBXBuildFile; fileRef = 838485BD0D6D687300CEA253 /* message.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 83A4AEDC1EA0840800ACADDE /* module.modulemap in Headers */ = {isa = PBXBuildFile; fileRef = 83A4AED71EA06D9D00ACADDE /* module.modulemap */; settings = {ATTRIBUTES = (Public, ); }; }; + 83A4AEDE1EA08C7200ACADDE /* ObjectiveC.apinotes in Headers */ = {isa = PBXBuildFile; fileRef = 83A4AEDD1EA08C5700ACADDE /* ObjectiveC.apinotes */; settings = {ATTRIBUTES = (Public, ); }; }; 83B1A8BE0FF1AC0D0019EA5B /* objc-msg-simulator-i386.s in Sources */ = {isa = PBXBuildFile; fileRef = 83B1A8BC0FF1AC0D0019EA5B /* objc-msg-simulator-i386.s */; }; 83BE02E40FCCB23400661494 /* objc-file-old.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83BE02E30FCCB23400661494 /* objc-file-old.mm */; }; 83BE02E80FCCB24D00661494 /* objc-file-old.h in Headers */ = {isa = PBXBuildFile; fileRef = 83BE02E50FCCB24D00661494 /* objc-file-old.h */; }; @@ -184,12 +186,15 @@ 8384861A0D6D68A800CEA253 /* runtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = runtime.h; path = runtime/runtime.h; sourceTree = ""; }; 838486230D6D68F000CEA253 /* List.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = List.m; path = runtime/OldClasses.subproj/List.m; sourceTree = ""; }; 838486240D6D68F000CEA253 /* List.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = List.h; path = runtime/OldClasses.subproj/List.h; sourceTree = ""; }; + 83A4AED71EA06D9D00ACADDE /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; name = module.modulemap; path = runtime/Module/module.modulemap; sourceTree = ""; }; + 83A4AEDD1EA08C5700ACADDE /* ObjectiveC.apinotes */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = ObjectiveC.apinotes; path = runtime/Module/ObjectiveC.apinotes; sourceTree = ""; }; 83B1A8BC0FF1AC0D0019EA5B /* objc-msg-simulator-i386.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = "objc-msg-simulator-i386.s"; path = "runtime/Messengers.subproj/objc-msg-simulator-i386.s"; sourceTree = ""; }; 83BE02E30FCCB23400661494 /* objc-file-old.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "objc-file-old.mm"; path = "runtime/objc-file-old.mm"; sourceTree = ""; }; 83BE02E50FCCB24D00661494 /* objc-file-old.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "objc-file-old.h"; path = "runtime/objc-file-old.h"; sourceTree = ""; }; 83BE02E60FCCB24D00661494 /* objc-file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "objc-file.h"; path = "runtime/objc-file.h"; sourceTree = ""; }; 83BE02E70FCCB24D00661494 /* objc-runtime-old.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "objc-runtime-old.h"; path = "runtime/objc-runtime-old.h"; sourceTree = ""; }; 83C9C3381668B50E00F4E544 /* objc-msg-simulator-x86_64.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = "objc-msg-simulator-x86_64.s"; path = "runtime/Messengers.subproj/objc-msg-simulator-x86_64.s"; sourceTree = ""; }; + 83CE671D1E6E76B60095A33E /* interposable.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = interposable.txt; sourceTree = ""; }; 83D49E4E13C7C84F0057F1DD /* objc-msg-arm64.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = "objc-msg-arm64.s"; path = "runtime/Messengers.subproj/objc-msg-arm64.s"; sourceTree = ""; }; 83EB007A121C9EC200B92C16 /* objc-sel-table.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = "objc-sel-table.s"; path = "runtime/objc-sel-table.s"; sourceTree = ""; }; 83F4B52615E843B100E0926F /* NSObjCRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSObjCRuntime.h; path = runtime/NSObjCRuntime.h; sourceTree = ""; }; @@ -301,6 +306,7 @@ 830F2AA50D7394C200392440 /* markgc.cpp */, 838485B40D6D683300CEA253 /* APPLE_LICENSE */, 838485B50D6D683300CEA253 /* ReleaseNotes.rtf */, + 83CE671D1E6E76B60095A33E /* interposable.txt */, 838485B30D6D682B00CEA253 /* libobjc.order */, ); name = Other; @@ -309,6 +315,8 @@ 838485C60D6D687700CEA253 /* Public Headers */ = { isa = PBXGroup; children = ( + 83A4AEDD1EA08C5700ACADDE /* ObjectiveC.apinotes */, + 83A4AED71EA06D9D00ACADDE /* module.modulemap */, 83F4B52615E843B100E0926F /* NSObjCRuntime.h */, 83F4B52715E843B100E0926F /* NSObject.h */, 838485BD0D6D687300CEA253 /* message.h */, @@ -383,6 +391,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 83A4AEDE1EA08C7200ACADDE /* ObjectiveC.apinotes in Headers */, + 83A4AEDC1EA0840800ACADDE /* module.modulemap in Headers */, 830F2A980D738DC200392440 /* hashtable.h in Headers */, 838485BF0D6D687300CEA253 /* hashtable2.h in Headers */, 838486260D6D68F000CEA253 /* List.h in Headers */, @@ -503,7 +513,7 @@ ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "cd \"${INSTALL_DIR}\"\n/bin/ln -s libobjc.A.dylib libobjc.dylib\n"; + shellScript = "cd \"${INSTALL_DIR}\"\n/bin/ln -s libobjc.A.dylib libobjc.dylib\n\nTBD_UPPER=`echo ${GENERATE_TEXT_BASED_STUBS} | tr a-z A-Z`\n\nif [ ${TBD_UPPER} = \"YES\" ] || [ ${TBD_UPPER} = \"TRUE\" ] || [ ${TBD_UPPER} = \"1\" ]; then\nGENERATE_TBD=1\nfi\n\nif [ ${GENERATE_TBD} ]; then\n /bin/ln -s libobjc.A.tbd libobjc.tbd\nfi\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -579,6 +589,9 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + COPY_HEADERS_RUN_UNIFDEF = YES; + COPY_HEADERS_UNIFDEF_FLAGS = "-UBUILD_FOR_OSX"; + "COPY_HEADERS_UNIFDEF_FLAGS[sdk=macosx*]" = "-DBUILD_FOR_OSX"; COPY_PHASE_STRIP = NO; DYLIB_CURRENT_VERSION = 228; EXECUTABLE_PREFIX = lib; @@ -610,8 +623,18 @@ __objc_data, "-Xlinker", 0x1000, + "-Xlinker", + "-interposable_list", + "-Xlinker", + interposable.txt, + ); + "OTHER_LDFLAGS[sdk=iphonesimulator*][arch=*]" = ( + "-lc++abi", + "-Xlinker", + "-interposable_list", + "-Xlinker", + interposable.txt, ); - "OTHER_LDFLAGS[sdk=iphonesimulator*][arch=*]" = "-lc++abi"; "OTHER_LDFLAGS[sdk=macosx*]" = ( "-lCrashReporterClient", "-lc++abi", @@ -623,6 +646,10 @@ __objc_data, "-Xlinker", 0x1000, + "-Xlinker", + "-interposable_list", + "-Xlinker", + interposable.txt, ); PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/objc; PRODUCT_NAME = objc.A; @@ -634,6 +661,9 @@ 1DEB914C08733D8E0010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + COPY_HEADERS_RUN_UNIFDEF = YES; + COPY_HEADERS_UNIFDEF_FLAGS = "-UBUILD_FOR_OSX"; + "COPY_HEADERS_UNIFDEF_FLAGS[sdk=macosx*]" = "-DBUILD_FOR_OSX"; DYLIB_CURRENT_VERSION = 228; EXECUTABLE_PREFIX = lib; GCC_CW_ASM_SYNTAX = NO; @@ -663,8 +693,18 @@ __objc_data, "-Xlinker", 0x1000, + "-Xlinker", + "-interposable_list", + "-Xlinker", + interposable.txt, + ); + "OTHER_LDFLAGS[sdk=iphonesimulator*][arch=*]" = ( + "-lc++abi", + "-Xlinker", + "-interposable_list", + "-Xlinker", + interposable.txt, ); - "OTHER_LDFLAGS[sdk=iphonesimulator*][arch=*]" = "-lc++abi"; "OTHER_LDFLAGS[sdk=macosx*]" = ( "-lCrashReporterClient", "-lc++abi", @@ -676,6 +716,10 @@ __objc_data, "-Xlinker", 0x1000, + "-Xlinker", + "-interposable_list", + "-Xlinker", + interposable.txt, ); PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/objc; PRODUCT_NAME = objc.A; diff --git a/runtime/Module/ObjectiveC.apinotes b/runtime/Module/ObjectiveC.apinotes new file mode 100644 index 0000000..5491c89 --- /dev/null +++ b/runtime/Module/ObjectiveC.apinotes @@ -0,0 +1,437 @@ +--- +Name: ObjectiveC +Classes: +- Name: NSArray + SwiftBridge: 'Swift.Array' +- Name: NSDictionary + SwiftBridge: 'Swift.Dictionary' +- Name: NSSet + SwiftBridge: 'Swift.Set' +- Name: NSString + SwiftBridge: 'Swift.String' +- Name: List + Methods: + - Selector: init + MethodKind: Instance + NullabilityOfRet: N + - Selector: 'isEqual:' + MethodKind: Instance + Nullability: + - O + NullabilityOfRet: S +- Name: NSObject + SwiftName: NSObject + Methods: + - Selector: alloc + MethodKind: Class + NullabilityOfRet: N + - Selector: 'allocWithZone:' + MethodKind: Class + Nullability: + - S + NullabilityOfRet: N + - Selector: class + MethodKind: Class + Availability: nonswift + AvailabilityMsg: use 'self' instead + - Selector: 'conformsToProtocol:' + MethodKind: Class + Nullability: + - N + NullabilityOfRet: S + - Selector: copy + MethodKind: Instance + NullabilityOfRet: N + - Selector: dealloc + MethodKind: Instance + Availability: nonswift + AvailabilityMsg: use 'deinit' to define a de-initializer + - Selector: debugDescription + MethodKind: Class + NullabilityOfRet: N + - Selector: description + MethodKind: Class + NullabilityOfRet: N + - Selector: 'forwardingTargetForSelector:' + MethodKind: Instance + Nullability: + - S + NullabilityOfRet: O + - Selector: 'forwardInvocation:' + MethodKind: Instance + Availability: nonswift + - Selector: init + MethodKind: Instance + NullabilityOfRet: N + DesignatedInit: true + - Selector: 'instanceMethodSignatureForSelector:' + MethodKind: Class + Availability: nonswift + - Selector: 'isSubclassOfClass:' + MethodKind: Class + Nullability: + - N + NullabilityOfRet: S + - Selector: 'methodSignatureForSelector:' + MethodKind: Instance + Availability: nonswift + - Selector: mutableCopy + MethodKind: Instance + NullabilityOfRet: N + - Selector: new + MethodKind: Class + NullabilityOfRet: N + - Selector: superclass + MethodKind: Class + NullabilityOfRet: O +- Name: Object + Methods: + - Selector: init + MethodKind: Instance + NullabilityOfRet: N + - Selector: 'isEqual:' + MethodKind: Instance + Nullability: + - O + NullabilityOfRet: S +Protocols: +- Name: NSObject + SwiftName: NSObjectProtocol + Methods: + - Selector: class + MethodKind: Instance + Availability: nonswift + AvailabilityMsg: use 'type(of:)' instead + - Selector: 'conformsToProtocol:' + MethodKind: Instance + Nullability: + - N + NullabilityOfRet: S + - Selector: 'isEqual:' + MethodKind: Instance + Nullability: + - O + NullabilityOfRet: S + - Selector: 'isKindOfClass:' + MethodKind: Instance + Nullability: + - N + NullabilityOfRet: S + - Selector: 'isMemberOfClass:' + MethodKind: Instance + Nullability: + - N + NullabilityOfRet: S + - Selector: self + MethodKind: Instance + NullabilityOfRet: N + Properties: + - Name: debugDescription + Nullability: N + - Name: description + Nullability: N + - Name: superclass + Nullability: O +Tags: +- Name: _NSZone + SwiftName: _NSZone + + +# Runtime functions did not yet have nullability in Swift 3. + +SwiftVersions: +- Version: 3 + Functions: + # objc.h swift3 + - Name: object_getClassName + NullabilityOfRet: U + Nullability: [U] + - Name: sel_isMapped + Nullability: [U] + - Name: sel_getUid + NullabilityOfRet: U + Nullability: [U] + + # objc-exception.h swift3 + - Name: objc_exception_throw + Nullability: [U] + - Name: objc_begin_catch + NullabilityOfRet: U + Nullability: [U] + - Name: objc_setExceptionPreprocessor + NullabilityOfRet: U + Nullability: [U] + - Name: objc_setExceptionMatcher + NullabilityOfRet: U + Nullability: [U] + - Name: objc_setUncaughtExceptionHandler + NullabilityOfRet: U + Nullability: [U] + - Name: objc_addExceptionHandler + Nullability: [U, U] + + # objc-sync.h swift3 + - Name: objc_sync_enter + Nullability: [U] + - Name: objc_sync_exit + Nullability: [U] + + # runtime.h swift3 + - Name: object_getClass + NullabilityOfRet: U + Nullability: [U] + - Name: object_setClass + NullabilityOfRet: U + Nullability: [U, U] + - Name: object_isClass + Nullability: [U] + - Name: object_getIvar + NullabilityOfRet: U + Nullability: [U, U] + - Name: object_setIvar + Nullability: [U, U, U] + - Name: object_setIvarWithStrongDefault + Nullability: [U, U, U] + - Name: objc_getClass + NullabilityOfRet: U + Nullability: [U] + - Name: objc_getMetaClass + NullabilityOfRet: U + Nullability: [U] + - Name: objc_lookUpClass + NullabilityOfRet: U + Nullability: [U] + - Name: objc_getRequiredClass + NullabilityOfRet: U + Nullability: [U] + - Name: objc_getClassList + Parameters: + - Position: 0 + Type: "Class _Nullable * _Null_unspecified" + - Name: objc_copyClassList + ResultType: "Class _Nullable * _Null_unspecified" + Nullability: [U] + - Name: class_getName + NullabilityOfRet: U + Nullability: [U] + - Name: class_isMetaClass + Nullability: [U] + - Name: class_getSuperclass + NullabilityOfRet: U + Nullability: [U] + - Name: class_getVersion + Nullability: [U] + - Name: class_setVersion + Nullability: [U] + - Name: class_getInstanceSize + Nullability: [U] + - Name: class_getInstanceVariable + NullabilityOfRet: U + Nullability: [U, U] + - Name: class_getClassVariable + NullabilityOfRet: U + Nullability: [U, U] + - Name: class_copyIvarList + ResultType: "Ivar _Nullable * _Null_unspecified" + Nullability: [U, U] + - Name: class_getInstanceMethod + NullabilityOfRet: U + Nullability: [U, U] + - Name: class_getClassMethod + NullabilityOfRet: U + Nullability: [U, U] + - Name: class_getMethodImplementation + NullabilityOfRet: U + Nullability: [U, U] + - Name: class_getMethodImplementation_stret + NullabilityOfRet: U + Nullability: [U, U] + - Name: class_respondsToSelector + Nullability: [U, U] + - Name: class_copyMethodList + Nullability: [U, U] + ResultType: "Method _Nullable * _Null_unspecified" + - Name: class_conformsToProtocol + Nullability: [U, U] + - Name: class_copyProtocolList +# fixme ResultType: + NullabilityOfRet: U + Nullability: [U, U] + - Name: class_getProperty + NullabilityOfRet: U + Nullability: [U, U] + - Name: class_copyPropertyList + ResultType: "objc_property_t _Nullable * _Null_unspecified" + Nullability: [U, U] + - Name: class_getIvarLayout + NullabilityOfRet: U + Nullability: [U] + - Name: class_getWeakIvarLayout + NullabilityOfRet: U + Nullability: [U] + - Name: class_addMethod + Nullability: [U, U, U, U] + - Name: class_replaceMethod + NullabilityOfRet: U + Nullability: [U, U, U, U] + - Name: class_addIvar + Nullability: [U, U, U, U, U] + - Name: class_addProtocol + Nullability: [U, U] + - Name: class_addProperty + Nullability: [U, U, U, U] + - Name: class_replaceProperty + Nullability: [U, U, U, U] + - Name: class_setIvarLayout + Nullability: [U, U] + - Name: class_setWeakIvarLayout + Nullability: [U, U] + - Name: class_createInstance + NullabilityOfRet: U + Nullability: [U, U] + - Name: objc_allocateClassPair + NullabilityOfRet: U + Nullability: [U, U, U] + - Name: objc_registerClassPair + Nullability: [U] + - Name: objc_duplicateClass + NullabilityOfRet: U + Nullability: [U, U, U] + - Name: objc_disposeClassPair + Nullability: [U] + - Name: method_getName + NullabilityOfRet: U + Nullability: [U] + - Name: method_getImplementation + NullabilityOfRet: U + Nullability: [U] + - Name: method_getTypeEncoding + NullabilityOfRet: U + Nullability: [U] + - Name: method_getNumberOfArguments + Nullability: [U] + - Name: method_copyReturnType + NullabilityOfRet: U + Nullability: [U] + - Name: method_copyArgumentType + NullabilityOfRet: U + Nullability: [U, U] + - Name: method_getReturnType + Nullability: [U, U, U] + - Name: method_getArgumentType + Nullability: [U, U, U, U] + - Name: method_getDescription + NullabilityOfRet: U + Nullability: [U] + - Name: method_setImplementation + NullabilityOfRet: U + Nullability: [U, U] + - Name: method_exchangeImplementations + Nullability: [U, U] + - Name: ivar_getName + NullabilityOfRet: U + Nullability: [U] + - Name: ivar_getTypeEncoding + NullabilityOfRet: U + Nullability: [U] + - Name: ivar_getOffset + Nullability: [U] + - Name: property_getName + NullabilityOfRet: U + Nullability: [U] + - Name: property_getAttributes + NullabilityOfRet: U + Nullability: [U] + - Name: property_copyAttributeList + NullabilityOfRet: U + Nullability: [U, U] + - Name: property_copyAttributeValue + NullabilityOfRet: U + Nullability: [U, U] + - Name: objc_getProtocol + NullabilityOfRet: U + Nullability: [U] + - Name: objc_copyProtocolList +# fixme ResultType: + NullabilityOfRet: U + Nullability: [U] + - Name: protocol_conformsToProtocol + Nullability: [U, U] + - Name: protocol_isEqual + Nullability: [U, U] + - Name: protocol_getName + NullabilityOfRet: U + Nullability: [U] + - Name: protocol_getMethodDescription + Nullability: [U, U, U, U] + - Name: protocol_copyMethodDescriptionList + NullabilityOfRet: U + Nullability: [U, U, U, U] + - Name: protocol_getProperty + NullabilityOfRet: U + Nullability: [U, U, U, U] + - Name: protocol_copyPropertyList + ResultType: "objc_property_t _Nullable * _Null_unspecified" + Nullability: [U, U] + - Name: protocol_copyPropertyList2 + ResultType: "objc_property_t _Nullable * _Null_unspecified" + Nullability: [U, U, U, U] + - Name: protocol_copyProtocolList +# fixme ResultType: + NullabilityOfRet: U + Nullability: [U, U] + - Name: objc_allocateProtocol + NullabilityOfRet: U + Nullability: [U] + - Name: objc_registerProtocol + Nullability: [U] + - Name: protocol_addMethodDescription + Nullability: [U, U, U, U, U] + - Name: protocol_addProtocol + Nullability: [U, U] + - Name: protocol_addProperty + Nullability: [U, U, U, U, U, U] + - Name: objc_copyImageNames + ResultType: "const char * _Nullable * _Null_unspecified" + Nullability: [U] + - Name: class_getImageName + NullabilityOfRet: U + Nullability: [U] + - Name: objc_copyClassNamesForImage + ResultType: "const char * _Nullable * _Null_unspecified" + Nullability: [U, U] + - Name: sel_getName + NullabilityOfRet: U + Nullability: [U] + - Name: sel_registerName + NullabilityOfRet: U + Nullability: [U] + - Name: sel_isEqual + Nullability: [U, U] + - Name: objc_enumerationMutation + Nullability: [U] + - Name: objc_setEnumerationMutationHandler + Nullability: [U] + - Name: objc_setForwardHandler + Nullability: [U, U] + - Name: imp_implementationWithBlock + NullabilityOfRet: U + Nullability: [U] + - Name: imp_getBlock + NullabilityOfRet: U + Nullability: [U] + - Name: imp_removeBlock + Nullability: [U] + - Name: objc_loadWeak + NullabilityOfRet: U + Nullability: [U] + - Name: objc_storeWeak + NullabilityOfRet: U + Nullability: [U, U] + - Name: objc_setAssociatedObject + Nullability: [U, U, U, U] + - Name: objc_getAssociatedObject + NullabilityOfRet: U + Nullability: [U, U] + - Name: objc_removeAssociatedObjects + Nullability: [U] diff --git a/runtime/Module/module.modulemap b/runtime/Module/module.modulemap new file mode 100644 index 0000000..74f7d64 --- /dev/null +++ b/runtime/Module/module.modulemap @@ -0,0 +1,40 @@ +module ObjectiveC [system] [extern_c] { + umbrella "." + export * + module * { + export * + } + + module NSObject { + requires objc + header "NSObject.h" + export * + } + +#if defined(BUILD_FOR_OSX) + module List { + // Uses @defs, which does not work in ObjC++ or non-ARC. + requires objc, !objc_arc, !cplusplus + header "List.h" + export * + } + + module Object { + requires objc + header "Object.h" + export * + } + + module Protocol { + requires objc + header "Protocol.h" + export * + } +#endif + +#if !defined(BUILD_FOR_OSX) + // These file are not available outside macOS. + exclude header "hashtable.h" + exclude header "hashtable2.h" +#endif +} diff --git a/runtime/NSObject.h b/runtime/NSObject.h index 7bd8611..2172aba 100644 --- a/runtime/NSObject.h +++ b/runtime/NSObject.h @@ -47,11 +47,14 @@ @end -OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) +OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) OBJC_ROOT_CLASS OBJC_EXPORT @interface NSObject { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-interface-ivars" Class isa OBJC_ISA_AVAILABILITY; +#pragma clang diagnostic pop } + (void)load; @@ -82,7 +85,7 @@ OBJC_EXPORT + (IMP)instanceMethodForSelector:(SEL)aSelector; - (void)doesNotRecognizeSelector:(SEL)aSelector; -- (id)forwardingTargetForSelector:(SEL)aSelector OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +- (id)forwardingTargetForSelector:(SEL)aSelector OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); - (void)forwardInvocation:(NSInvocation *)anInvocation OBJC_SWIFT_UNAVAILABLE(""); - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE(""); @@ -93,8 +96,8 @@ OBJC_EXPORT + (BOOL)isSubclassOfClass:(Class)aClass; -+ (BOOL)resolveClassMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -+ (BOOL)resolveInstanceMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); ++ (BOOL)resolveClassMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); ++ (BOOL)resolveInstanceMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + (NSUInteger)hash; + (Class)superclass; diff --git a/runtime/NSObject.mm b/runtime/NSObject.mm index 7a7b391..ec528a0 100644 --- a/runtime/NSObject.mm +++ b/runtime/NSObject.mm @@ -251,6 +251,22 @@ void SideTableLocksSucceedLock(const void *oldlock) { SideTables().succeedLock(oldlock); } +void SideTableLocksPrecedeLocks(StripedMap& newlocks) { + int i = 0; + const void *newlock; + while ((newlock = newlocks.getLock(i++))) { + SideTables().precedeLock(newlock); + } +} + +void SideTableLocksSucceedLocks(StripedMap& oldlocks) { + int i = 0; + const void *oldlock; + while ((oldlock = oldlocks.getLock(i++))) { + SideTables().succeedLock(oldlock); + } +} + // // The -fobjc-arc flag causes the compiler to issue calls to objc_{retain/release/autorelease/retain_block} // @@ -1070,7 +1086,7 @@ public: // Error. For bincompat purposes this is not // fatal in executables built with old SDKs. - if (DebugPoolAllocation || sdkIsAtLeast(10_12, 10_0, 10_0, 3_0)) { + if (DebugPoolAllocation || sdkIsAtLeast(10_12, 10_0, 10_0, 3_0, 2_0)) { // OBJC_DEBUG_POOL_ALLOCATION or new SDK. Bad pop is fatal. _objc_fatal ("Invalid or prematurely-freed autorelease pool %p.", token); diff --git a/runtime/Object.h b/runtime/Object.h index 5c857ac..86ce416 100644 --- a/runtime/Object.h +++ b/runtime/Object.h @@ -38,7 +38,8 @@ #if __OBJC__ && !__OBJC2__ __OSX_AVAILABLE(10.0) -__IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE +__IOS_UNAVAILABLE __TVOS_UNAVAILABLE +__WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE OBJC_ROOT_CLASS @interface Object { diff --git a/runtime/Object.mm b/runtime/Object.mm index 3ec14be..d5721aa 100644 --- a/runtime/Object.mm +++ b/runtime/Object.mm @@ -36,7 +36,8 @@ typedef struct objc_object *id; #if __OBJC2__ __OSX_AVAILABLE(10.0) -__IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE +__IOS_UNAVAILABLE __TVOS_UNAVAILABLE +__WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE OBJC_ROOT_CLASS @interface Object { Class isa; diff --git a/runtime/Protocol.h b/runtime/Protocol.h index 1f2a7b5..f5169be 100644 --- a/runtime/Protocol.h +++ b/runtime/Protocol.h @@ -41,7 +41,7 @@ // All methods of class Protocol are unavailable. // Use the functions in objc/runtime.h instead. -OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) +OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) @interface Protocol : NSObject @end @@ -50,7 +50,7 @@ OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) #include -OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) +OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) @interface Protocol : Object { @private @@ -74,12 +74,14 @@ OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) __OSX_DEPRECATED(10.0, 10.5, "use protocol_getMethodDescription instead") __IOS_DEPRECATED(2.0, 2.0, "use protocol_getMethodDescription instead") __TVOS_DEPRECATED(9.0, 9.0, "use protocol_getMethodDescription instead") - __WATCHOS_DEPRECATED(1.0, 1.0, "use protocol_getMethodDescription instead"); + __WATCHOS_DEPRECATED(1.0, 1.0, "use protocol_getMethodDescription instead") + __BRIDGEOS_DEPRECATED(2.0, 2.0, "use protocol_getMethodDescription instead"); - (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel __OSX_DEPRECATED(10.0, 10.5, "use protocol_getMethodDescription instead") __IOS_DEPRECATED(2.0, 2.0, "use protocol_getMethodDescription instead") __TVOS_DEPRECATED(9.0, 9.0, "use protocol_getMethodDescription instead") - __WATCHOS_DEPRECATED(1.0, 1.0, "use protocol_getMethodDescription instead"); + __WATCHOS_DEPRECATED(1.0, 1.0, "use protocol_getMethodDescription instead") + __BRIDGEOS_DEPRECATED(2.0, 2.0, "use protocol_getMethodDescription instead"); @end diff --git a/runtime/hashtable2.h b/runtime/hashtable2.h index 197a17f..a7dd3c8 100644 --- a/runtime/hashtable2.h +++ b/runtime/hashtable2.h @@ -32,7 +32,8 @@ #ifndef _OBJC_PRIVATE_H_ # define OBJC_HASH_AVAILABILITY \ __OSX_DEPRECATED(10.0, 10.1, "NXHashTable is deprecated") \ - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE \ + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE #else # define OBJC_HASH_AVAILABILITY #endif @@ -52,9 +53,13 @@ The objective C class HashTable is preferred when dealing with (key, values) ass As well-behaved scalable data structures, hash tables double in size when they start becoming full, thus guaranteeing both average constant time access and linear size. */ typedef struct { - uintptr_t (*hash)(const void *info, const void *data); - int (*isEqual)(const void *info, const void *data1, const void *data2); - void (*free)(const void *info, void *data); + uintptr_t (* _Nonnull hash)(const void * _Nullable info, + const void * _Nullable data); + int (* _Nonnull isEqual)(const void * _Nullable info, + const void * _Nullable data1, + const void * _Nullable data2); + void (* _Nonnull free)(const void * _Nullable info, + void * _Nullable data); int style; /* reserved for future expansion; currently 0 */ } NXHashTablePrototype; @@ -67,41 +72,63 @@ typedef struct { */ typedef struct { - const NXHashTablePrototype *prototype OBJC_HASH_AVAILABILITY; + const NXHashTablePrototype * _Nonnull prototype OBJC_HASH_AVAILABILITY; unsigned count OBJC_HASH_AVAILABILITY; unsigned nbBuckets OBJC_HASH_AVAILABILITY; - void *buckets OBJC_HASH_AVAILABILITY; - const void *info OBJC_HASH_AVAILABILITY; + void * _Nullable buckets OBJC_HASH_AVAILABILITY; + const void * _Nullable info OBJC_HASH_AVAILABILITY; } NXHashTable OBJC_HASH_AVAILABILITY; /* private data structure; may change */ -OBJC_EXPORT NXHashTable *NXCreateHashTableFromZone (NXHashTablePrototype prototype, unsigned capacity, const void *info, void *z) OBJC_HASH_AVAILABILITY; -OBJC_EXPORT NXHashTable *NXCreateHashTable (NXHashTablePrototype prototype, unsigned capacity, const void *info) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT NXHashTable * _Nonnull +NXCreateHashTableFromZone (NXHashTablePrototype prototype, unsigned capacity, + const void * _Nullable info, void * _Nullable z) + OBJC_HASH_AVAILABILITY; + +OBJC_EXPORT NXHashTable * _Nonnull +NXCreateHashTable (NXHashTablePrototype prototype, unsigned capacity, + const void * _Nullable info) + OBJC_HASH_AVAILABILITY; /* if hash is 0, pointer hash is assumed */ /* if isEqual is 0, pointer equality is assumed */ /* if free is 0, elements are not freed */ /* capacity is only a hint; 0 creates a small table */ /* info allows call backs to be very general */ -OBJC_EXPORT void NXFreeHashTable (NXHashTable *table) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT void +NXFreeHashTable (NXHashTable * _Nonnull table) + OBJC_HASH_AVAILABILITY; /* calls free for each data, and recovers table */ -OBJC_EXPORT void NXEmptyHashTable (NXHashTable *table) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT void +NXEmptyHashTable (NXHashTable * _Nonnull table) + OBJC_HASH_AVAILABILITY; /* does not deallocate table nor data; keeps current capacity */ -OBJC_EXPORT void NXResetHashTable (NXHashTable *table) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT void +NXResetHashTable (NXHashTable * _Nonnull table) + OBJC_HASH_AVAILABILITY; /* frees each entry; keeps current capacity */ -OBJC_EXPORT BOOL NXCompareHashTables (NXHashTable *table1, NXHashTable *table2) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT BOOL +NXCompareHashTables (NXHashTable * _Nonnull table1, + NXHashTable * _Nonnull table2) + OBJC_HASH_AVAILABILITY; /* Returns YES if the two sets are equal (each member of table1 in table2, and table have same size) */ -OBJC_EXPORT NXHashTable *NXCopyHashTable (NXHashTable *table) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT NXHashTable * _Nonnull +NXCopyHashTable (NXHashTable * _Nonnull table) + OBJC_HASH_AVAILABILITY; /* makes a fresh table, copying data pointers, not data itself. */ -OBJC_EXPORT unsigned NXCountHashTable (NXHashTable *table) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT unsigned +NXCountHashTable (NXHashTable * _Nonnull table) + OBJC_HASH_AVAILABILITY; /* current number of data in table */ -OBJC_EXPORT int NXHashMember (NXHashTable *table, const void *data) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT int +NXHashMember (NXHashTable * _Nonnull table, const void * _Nullable data) + OBJC_HASH_AVAILABILITY; /* returns non-0 iff data is present in table. Example of use when the hashed data is a struct containing the key, and when the callee only has a key: @@ -110,7 +137,9 @@ OBJC_EXPORT int NXHashMember (NXHashTable *table, const void *data) OBJC_HASH_AV return NXHashMember (myTable, &pseudo) */ -OBJC_EXPORT void *NXHashGet (NXHashTable *table, const void *data) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT void * _Nullable +NXHashGet (NXHashTable * _Nonnull table, const void * _Nullable data) + OBJC_HASH_AVAILABILITY; /* return original table data or NULL. Example of use when the hashed data is a struct containing the key, and when the callee only has a key: @@ -120,14 +149,20 @@ OBJC_EXPORT void *NXHashGet (NXHashTable *table, const void *data) OBJC_HASH_AVA original = NXHashGet (myTable, &pseudo) */ -OBJC_EXPORT void *NXHashInsert (NXHashTable *table, const void *data) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT void * _Nullable +NXHashInsert (NXHashTable * _Nonnull table, const void * _Nullable data) + OBJC_HASH_AVAILABILITY; /* previous data or NULL is returned. */ -OBJC_EXPORT void *NXHashInsertIfAbsent (NXHashTable *table, const void *data) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT void * _Nullable +NXHashInsertIfAbsent (NXHashTable * _Nonnull table, const void * _Nullable data) + OBJC_HASH_AVAILABILITY; /* If data already in table, returns the one in table else adds argument to table and returns argument. */ -OBJC_EXPORT void *NXHashRemove (NXHashTable *table, const void *data) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT void * _Nullable +NXHashRemove (NXHashTable * _Nonnull table, const void * _Nullable data) + OBJC_HASH_AVAILABILITY; /* previous data or NULL is returned */ /* Iteration over all elements of a table consists in setting up an iteration state and then to progress until all entries have been visited. An example of use for counting elements in a table is: @@ -142,9 +177,13 @@ OBJC_EXPORT void *NXHashRemove (NXHashTable *table, const void *data) OBJC_HASH_ typedef struct {int i; int j;} NXHashState OBJC_HASH_AVAILABILITY; /* callers should not rely on actual contents of the struct */ -OBJC_EXPORT NXHashState NXInitHashState(NXHashTable *table) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT NXHashState +NXInitHashState(NXHashTable * _Nonnull table) + OBJC_HASH_AVAILABILITY; -OBJC_EXPORT int NXNextHashState(NXHashTable *table, NXHashState *state, void **data) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT int +NXNextHashState(NXHashTable * _Nonnull table, NXHashState * _Nonnull state, + void * _Nullable * _Nonnull data) OBJC_HASH_AVAILABILITY; /* returns 0 when all elements have been visited */ /************************************************************************* @@ -152,23 +191,45 @@ OBJC_EXPORT int NXNextHashState(NXHashTable *table, NXHashState *state, void **d * and common prototypes *************************************************************************/ -OBJC_EXPORT uintptr_t NXPtrHash(const void *info, const void *data) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT uintptr_t +NXPtrHash(const void * _Nullable info, const void * _Nullable data) + OBJC_HASH_AVAILABILITY; /* scrambles the address bits; info unused */ -OBJC_EXPORT uintptr_t NXStrHash(const void *info, const void *data) OBJC_HASH_AVAILABILITY; + +OBJC_EXPORT uintptr_t +NXStrHash(const void * _Nullable info, const void * _Nullable data) + OBJC_HASH_AVAILABILITY; /* string hashing; info unused */ -OBJC_EXPORT int NXPtrIsEqual(const void *info, const void *data1, const void *data2) OBJC_HASH_AVAILABILITY; + +OBJC_EXPORT int +NXPtrIsEqual(const void * _Nullable info, const void * _Nullable data1, + const void * _Nullable data2) + OBJC_HASH_AVAILABILITY; /* pointer comparison; info unused */ -OBJC_EXPORT int NXStrIsEqual(const void *info, const void *data1, const void *data2) OBJC_HASH_AVAILABILITY; + +OBJC_EXPORT int +NXStrIsEqual(const void * _Nullable info, const void * _Nullable data1, + const void * _Nullable data2) + OBJC_HASH_AVAILABILITY; /* string comparison; NULL ok; info unused */ -OBJC_EXPORT void NXNoEffectFree(const void *info, void *data) OBJC_HASH_AVAILABILITY; + +OBJC_EXPORT void +NXNoEffectFree(const void * _Nullable info, void * _Nullable data) + OBJC_HASH_AVAILABILITY; /* no effect; info unused */ -OBJC_EXPORT void NXReallyFree(const void *info, void *data) OBJC_HASH_AVAILABILITY; + +OBJC_EXPORT void +NXReallyFree(const void * _Nullable info, void * _Nullable data) + OBJC_HASH_AVAILABILITY; /* frees it; info unused */ /* The two following prototypes are useful for manipulating set of pointers or set of strings; For them free is defined as NXNoEffectFree */ -OBJC_EXPORT const NXHashTablePrototype NXPtrPrototype OBJC_HASH_AVAILABILITY; +OBJC_EXPORT const NXHashTablePrototype NXPtrPrototype + OBJC_HASH_AVAILABILITY; /* prototype when data is a pointer (void *) */ -OBJC_EXPORT const NXHashTablePrototype NXStrPrototype OBJC_HASH_AVAILABILITY; + +OBJC_EXPORT const NXHashTablePrototype NXStrPrototype + OBJC_HASH_AVAILABILITY; /* prototype when data is a string (char *) */ /* following prototypes help describe mappings where the key is the first element of a struct and is either a pointer or a string. @@ -181,8 +242,10 @@ For example NXStrStructKeyPrototype can be used to hash pointers to Example, whe For the following prototypes, free is defined as NXReallyFree. */ -OBJC_EXPORT const NXHashTablePrototype NXPtrStructKeyPrototype OBJC_HASH_AVAILABILITY; -OBJC_EXPORT const NXHashTablePrototype NXStrStructKeyPrototype OBJC_HASH_AVAILABILITY; +OBJC_EXPORT const NXHashTablePrototype NXPtrStructKeyPrototype + OBJC_HASH_AVAILABILITY; +OBJC_EXPORT const NXHashTablePrototype NXStrStructKeyPrototype + OBJC_HASH_AVAILABILITY; #if !__OBJC2__ && !TARGET_OS_WIN32 @@ -196,29 +259,39 @@ A unique string is a string that is allocated once for all (never de-allocated) typedef const char *NXAtom OBJC_HASH_AVAILABILITY; -OBJC_EXPORT NXAtom NXUniqueString(const char *buffer) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT NXAtom _Nullable +NXUniqueString(const char * _Nullable buffer) + OBJC_HASH_AVAILABILITY; /* assumes that buffer is \0 terminated, and returns a previously created string or a new string that is a copy of buffer. If NULL is passed returns NULL. Returned string should never be modified. To ensure this invariant, allocations are made in a special read only zone. */ -OBJC_EXPORT NXAtom NXUniqueStringWithLength(const char *buffer, int length) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT NXAtom _Nonnull +NXUniqueStringWithLength(const char * _Nullable buffer, int length) + OBJC_HASH_AVAILABILITY; /* assumes that buffer is a non NULL buffer of at least length characters. Returns a previously created string or a new string that is a copy of buffer. If buffer contains \0, string will be truncated. As for NXUniqueString, returned string should never be modified. */ -OBJC_EXPORT NXAtom NXUniqueStringNoCopy(const char *string) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT NXAtom _Nullable +NXUniqueStringNoCopy(const char * _Nullable string) + OBJC_HASH_AVAILABILITY; /* If there is already a unique string equal to string, returns the original. Otherwise, string is entered in the table, without making a copy. Argument should then never be modified. */ -OBJC_EXPORT char *NXCopyStringBuffer(const char *buffer) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT char * _Nullable +NXCopyStringBuffer(const char * _Nullable buffer) + OBJC_HASH_AVAILABILITY; /* given a buffer, allocates a new string copy of buffer. Buffer should be \0 terminated; returned string is \0 terminated. */ -OBJC_EXPORT char *NXCopyStringBufferFromZone(const char *buffer, void *z) OBJC_HASH_AVAILABILITY; +OBJC_EXPORT char * _Nullable +NXCopyStringBufferFromZone(const char * _Nullable buffer, void * _Nullable z) + OBJC_HASH_AVAILABILITY; /* given a buffer, allocates a new string copy of buffer. Buffer should be \0 terminated; returned string is \0 terminated. */ diff --git a/runtime/maptable.h b/runtime/maptable.h index e43da78..248c18f 100644 --- a/runtime/maptable.h +++ b/runtime/maptable.h @@ -32,7 +32,8 @@ #ifndef _OBJC_PRIVATE_H_ # define OBJC_MAP_AVAILABILITY \ __OSX_DEPRECATED(10.0, 10.1, "NXMapTable is deprecated") \ - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE \ + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE #else # define OBJC_MAP_AVAILABILITY #endif @@ -49,16 +50,21 @@ __BEGIN_DECLS typedef struct _NXMapTable { /* private data structure; may change */ - const struct _NXMapTablePrototype *prototype; + const struct _NXMapTablePrototype * _Nonnull prototype; unsigned count; unsigned nbBucketsMinusOne; - void *buckets; + void * _Nullable buckets; } NXMapTable OBJC_MAP_AVAILABILITY; typedef struct _NXMapTablePrototype { - unsigned (*hash)(NXMapTable *, const void *key); - int (*isEqual)(NXMapTable *, const void *key1, const void *key2); - void (*free)(NXMapTable *, void *key, void *value); + unsigned (* _Nonnull hash)(NXMapTable * _Nonnull, + const void * _Nullable key); + int (* _Nonnull isEqual)(NXMapTable * _Nonnull, + const void * _Nullable key1, + const void * _Nullable key2); + void (* _Nonnull free)(NXMapTable * _Nonnull, + void * _Nullable key, + void * _Nullable value); int style; /* reserved for future expansion; currently 0 */ } NXMapTablePrototype OBJC_MAP_AVAILABILITY; @@ -70,36 +76,59 @@ typedef struct _NXMapTablePrototype { C - isEqual(key1, key2) => key1 == key2 */ -#define NX_MAPNOTAKEY ((void *)(-1)) +#define NX_MAPNOTAKEY ((void * _Nonnull)(-1)) /*************** Functions ***************/ -OBJC_EXPORT NXMapTable *NXCreateMapTableFromZone(NXMapTablePrototype prototype, unsigned capacity, void *z) OBJC_MAP_AVAILABILITY; -OBJC_EXPORT NXMapTable *NXCreateMapTable(NXMapTablePrototype prototype, unsigned capacity) OBJC_MAP_AVAILABILITY; +OBJC_EXPORT NXMapTable * _Nonnull +NXCreateMapTableFromZone(NXMapTablePrototype prototype, + unsigned capacity, void * _Nullable z) + OBJC_MAP_AVAILABILITY; + +OBJC_EXPORT NXMapTable * _Nonnull +NXCreateMapTable(NXMapTablePrototype prototype, unsigned capacity) + OBJC_MAP_AVAILABILITY; /* capacity is only a hint; 0 creates a small table */ -OBJC_EXPORT void NXFreeMapTable(NXMapTable *table) OBJC_MAP_AVAILABILITY; +OBJC_EXPORT void +NXFreeMapTable(NXMapTable * _Nonnull table) + OBJC_MAP_AVAILABILITY; /* call free for each pair, and recovers table */ -OBJC_EXPORT void NXResetMapTable(NXMapTable *table) OBJC_MAP_AVAILABILITY; +OBJC_EXPORT void +NXResetMapTable(NXMapTable * _Nonnull table) + OBJC_MAP_AVAILABILITY; /* free each pair; keep current capacity */ -OBJC_EXPORT BOOL NXCompareMapTables(NXMapTable *table1, NXMapTable *table2) OBJC_MAP_AVAILABILITY; +OBJC_EXPORT BOOL +NXCompareMapTables(NXMapTable * _Nonnull table1, NXMapTable * _Nonnull table2) + OBJC_MAP_AVAILABILITY; /* Returns YES if the two sets are equal (each member of table1 in table2, and table have same size) */ -OBJC_EXPORT unsigned NXCountMapTable(NXMapTable *table) OBJC_MAP_AVAILABILITY; +OBJC_EXPORT unsigned +NXCountMapTable(NXMapTable * _Nonnull table) + OBJC_MAP_AVAILABILITY; /* current number of data in table */ -OBJC_EXPORT void *NXMapMember(NXMapTable *table, const void *key, void **value) OBJC_MAP_AVAILABILITY; +OBJC_EXPORT void * _Nullable +NXMapMember(NXMapTable * _Nonnull table, const void * _Nullable key, + void * _Nullable * _Nonnull value) OBJC_MAP_AVAILABILITY; /* return original table key or NX_MAPNOTAKEY. If key is found, value is set */ -OBJC_EXPORT void *NXMapGet(NXMapTable *table, const void *key) OBJC_MAP_AVAILABILITY; +OBJC_EXPORT void * _Nullable +NXMapGet(NXMapTable * _Nonnull table, const void * _Nullable key) + OBJC_MAP_AVAILABILITY; /* return original corresponding value or NULL. When NULL need be stored as value, NXMapMember can be used to test for presence */ -OBJC_EXPORT void *NXMapInsert(NXMapTable *table, const void *key, const void *value) OBJC_MAP_AVAILABILITY; +OBJC_EXPORT void * _Nullable +NXMapInsert(NXMapTable * _Nonnull table, const void * _Nullable key, + const void * _Nullable value) + OBJC_MAP_AVAILABILITY; /* override preexisting pair; Return previous value or NULL. */ -OBJC_EXPORT void *NXMapRemove(NXMapTable *table, const void *key) OBJC_MAP_AVAILABILITY; +OBJC_EXPORT void * _Nullable +NXMapRemove(NXMapTable * _Nonnull table, const void * _Nullable key) + OBJC_MAP_AVAILABILITY; /* previous value or NULL is returned */ /* Iteration over all elements of a table consists in setting up an iteration state and then to progress until all entries have been visited. An example of use for counting elements in a table is: @@ -115,22 +144,31 @@ OBJC_EXPORT void *NXMapRemove(NXMapTable *table, const void *key) OBJC_MAP_AVAIL typedef struct {int index;} NXMapState OBJC_MAP_AVAILABILITY; /* callers should not rely on actual contents of the struct */ -OBJC_EXPORT NXMapState NXInitMapState(NXMapTable *table) OBJC_MAP_AVAILABILITY; +OBJC_EXPORT NXMapState +NXInitMapState(NXMapTable * _Nonnull table) + OBJC_MAP_AVAILABILITY; -OBJC_EXPORT int NXNextMapState(NXMapTable *table, NXMapState *state, const void **key, const void **value) OBJC_MAP_AVAILABILITY; +OBJC_EXPORT int +NXNextMapState(NXMapTable * _Nonnull table, NXMapState * _Nonnull state, + const void * _Nullable * _Nonnull key, + const void * _Nullable * _Nonnull value) + OBJC_MAP_AVAILABILITY; /* returns 0 when all elements have been visited */ /*************** Conveniences ***************/ -OBJC_EXPORT const NXMapTablePrototype NXPtrValueMapPrototype OBJC_MAP_AVAILABILITY; +OBJC_EXPORT const NXMapTablePrototype NXPtrValueMapPrototype + OBJC_MAP_AVAILABILITY; /* hashing is pointer/integer hashing; isEqual is identity; free is no-op. */ -OBJC_EXPORT const NXMapTablePrototype NXStrValueMapPrototype OBJC_MAP_AVAILABILITY; +OBJC_EXPORT const NXMapTablePrototype NXStrValueMapPrototype + OBJC_MAP_AVAILABILITY; /* hashing is string hashing; isEqual is strcmp; free is no-op. */ -OBJC_EXPORT const NXMapTablePrototype NXObjectMapPrototype OBJC2_UNAVAILABLE; +OBJC_EXPORT const NXMapTablePrototype NXObjectMapPrototype + OBJC2_UNAVAILABLE; /* for objects; uses methods: hash, isEqual:, free, all for key. */ __END_DECLS diff --git a/runtime/message.h b/runtime/message.h index 725e912..a53b430 100644 --- a/runtime/message.h +++ b/runtime/message.h @@ -24,27 +24,23 @@ #ifndef _OBJC_MESSAGE_H #define _OBJC_MESSAGE_H -#pragma GCC system_header - #include #include -#pragma GCC system_header - #ifndef OBJC_SUPER #define OBJC_SUPER /// Specifies the superclass of an instance. struct objc_super { /// Specifies an instance of a class. - __unsafe_unretained id receiver; + __unsafe_unretained _Nonnull id receiver; /// Specifies the particular superclass of the instance to message. #if !defined(__cplusplus) && !__OBJC2__ /* For compatibility with old objc-runtime.h header */ - __unsafe_unretained Class class; + __unsafe_unretained _Nonnull Class class; #else - __unsafe_unretained Class super_class; + __unsafe_unretained _Nonnull Class super_class; #endif /* super_class is the first class to search */ }; @@ -61,10 +57,13 @@ struct objc_super { * before being called. */ #if !OBJC_OLD_DISPATCH_PROTOTYPES -OBJC_EXPORT void objc_msgSend(void /* id self, SEL op, ... */ ) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); -OBJC_EXPORT void objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ ) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT void +objc_msgSend(void /* id self, SEL op, ... */ ) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ ) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); #else /** * Sends a message with a simple return value to an instance of a class. @@ -82,8 +81,9 @@ OBJC_EXPORT void objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... * other messages are sent using \c objc_msgSend. Methods that have data structures as return values * are sent using \c objc_msgSendSuper_stret and \c objc_msgSend_stret. */ -OBJC_EXPORT id objc_msgSend(id self, SEL op, ...) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_msgSend(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Sends a message with a simple return value to the superclass of an instance of a class. * @@ -98,8 +98,9 @@ OBJC_EXPORT id objc_msgSend(id self, SEL op, ...) * * @see objc_msgSend */ -OBJC_EXPORT id objc_msgSendSuper(struct objc_super *super, SEL op, ...) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); #endif @@ -113,11 +114,14 @@ OBJC_EXPORT id objc_msgSendSuper(struct objc_super *super, SEL op, ...) * before being called. */ #if !OBJC_OLD_DISPATCH_PROTOTYPES -OBJC_EXPORT void objc_msgSend_stret(void /* id self, SEL op, ... */ ) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) +OBJC_EXPORT void +objc_msgSend_stret(void /* id self, SEL op, ... */ ) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; -OBJC_EXPORT void objc_msgSendSuper_stret(void /* struct objc_super *super, SEL op, ... */ ) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) + +OBJC_EXPORT void +objc_msgSendSuper_stret(void /* struct objc_super *super, SEL op, ... */ ) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; #else /** @@ -125,8 +129,9 @@ OBJC_EXPORT void objc_msgSendSuper_stret(void /* struct objc_super *super, SEL o * * @see objc_msgSend */ -OBJC_EXPORT void objc_msgSend_stret(id self, SEL op, ...) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) +OBJC_EXPORT void +objc_msgSend_stret(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; /** @@ -134,8 +139,10 @@ OBJC_EXPORT void objc_msgSend_stret(id self, SEL op, ...) * * @see objc_msgSendSuper */ -OBJC_EXPORT void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) +OBJC_EXPORT void +objc_msgSendSuper_stret(struct objc_super * _Nonnull super, + SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; #endif @@ -161,15 +168,19 @@ OBJC_EXPORT void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...) # if defined(__i386__) -OBJC_EXPORT void objc_msgSend_fpret(void /* id self, SEL op, ... */ ) - OBJC_AVAILABLE(10.4, 2.0, 9.0, 1.0); +OBJC_EXPORT void +objc_msgSend_fpret(void /* id self, SEL op, ... */ ) + OBJC_AVAILABLE(10.4, 2.0, 9.0, 1.0, 2.0); # elif defined(__x86_64__) -OBJC_EXPORT void objc_msgSend_fpret(void /* id self, SEL op, ... */ ) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -OBJC_EXPORT void objc_msgSend_fp2ret(void /* id self, SEL op, ... */ ) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +objc_msgSend_fpret(void /* id self, SEL op, ... */ ) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_msgSend_fp2ret(void /* id self, SEL op, ... */ ) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); # endif @@ -187,8 +198,9 @@ OBJC_EXPORT void objc_msgSend_fp2ret(void /* id self, SEL op, ... */ ) * you must use \c objc_msgSend_fpret for functions returning non-integral type. For \c float or * \c long \c double return types, cast the function to an appropriate function pointer type first. */ -OBJC_EXPORT double objc_msgSend_fpret(id self, SEL op, ...) - OBJC_AVAILABLE(10.4, 2.0, 9.0, 1.0); +OBJC_EXPORT double +objc_msgSend_fpret(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.4, 2.0, 9.0, 1.0, 2.0); /* Use objc_msgSendSuper() for fp-returning messages to super. */ /* See also objc_msgSendv_fpret() below. */ @@ -199,15 +211,17 @@ OBJC_EXPORT double objc_msgSend_fpret(id self, SEL op, ...) * * @see objc_msgSend */ -OBJC_EXPORT long double objc_msgSend_fpret(id self, SEL op, ...) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT long double +objc_msgSend_fpret(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); # if __STDC_VERSION__ >= 199901L -OBJC_EXPORT _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT _Complex long double +objc_msgSend_fp2ret(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); # else -OBJC_EXPORT void objc_msgSend_fp2ret(id self, SEL op, ...) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void objc_msgSend_fp2ret(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); # endif /* Use objc_msgSendSuper() for fp-returning messages to super. */ @@ -229,16 +243,22 @@ OBJC_EXPORT void objc_msgSend_fp2ret(id self, SEL op, ...) * before being called. */ #if !OBJC_OLD_DISPATCH_PROTOTYPES -OBJC_EXPORT void method_invoke(void /* id receiver, Method m, ... */ ) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -OBJC_EXPORT void method_invoke_stret(void /* id receiver, Method m, ... */ ) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0) +OBJC_EXPORT void +method_invoke(void /* id receiver, Method m, ... */ ) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +method_invoke_stret(void /* id receiver, Method m, ... */ ) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; #else -OBJC_EXPORT id method_invoke(id receiver, Method m, ...) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -OBJC_EXPORT void method_invoke_stret(id receiver, Method m, ...) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0) +OBJC_EXPORT id _Nullable +method_invoke(id _Nullable receiver, Method _Nonnull m, ...) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +method_invoke_stret(id _Nullable receiver, Method _Nonnull m, ...) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; #endif @@ -259,16 +279,22 @@ OBJC_EXPORT void method_invoke_stret(id receiver, Method m, ...) * but may be compared to other IMP values. */ #if !OBJC_OLD_DISPATCH_PROTOTYPES -OBJC_EXPORT void _objc_msgForward(void /* id receiver, SEL sel, ... */ ) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); -OBJC_EXPORT void _objc_msgForward_stret(void /* id receiver, SEL sel, ... */ ) - OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0) +OBJC_EXPORT void +_objc_msgForward(void /* id receiver, SEL sel, ... */ ) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +_objc_msgForward_stret(void /* id receiver, SEL sel, ... */ ) + OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; #else -OBJC_EXPORT id _objc_msgForward(id receiver, SEL sel, ...) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); -OBJC_EXPORT void _objc_msgForward_stret(id receiver, SEL sel, ...) - OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0) +OBJC_EXPORT id _Nullable +_objc_msgForward(id _Nonnull receiver, SEL _Nonnull sel, ...) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +_objc_msgForward_stret(id _Nonnull receiver, SEL _Nonnull sel, ...) + OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; #endif @@ -288,14 +314,25 @@ OBJC_EXPORT void _objc_msgForward_stret(id receiver, SEL sel, ...) typedef void* marg_list; -OBJC_EXPORT id objc_msgSendv(id self, SEL op, size_t arg_size, marg_list arg_frame) OBJC2_UNAVAILABLE; -OBJC_EXPORT void objc_msgSendv_stret(void *stretAddr, id self, SEL op, size_t arg_size, marg_list arg_frame) OBJC2_UNAVAILABLE; +OBJC_EXPORT id _Nullable +objc_msgSendv(id _Nullable self, SEL _Nonnull op, size_t arg_size, + marg_list _Nonnull arg_frame) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +objc_msgSendv_stret(void * _Nonnull stretAddr, id _Nullable self, + SEL _Nonnull op, size_t arg_size, + marg_list _Nullable arg_frame) + OBJC2_UNAVAILABLE; /* Note that objc_msgSendv_stret() does not return a structure type, * and should not be cast to do so. This is unlike objc_msgSend_stret() * and objc_msgSendSuper_stret(). */ #if defined(__i386__) -OBJC_EXPORT double objc_msgSendv_fpret(id self, SEL op, unsigned arg_size, marg_list arg_frame) OBJC2_UNAVAILABLE; +OBJC_EXPORT double +objc_msgSendv_fpret(id _Nullable self, SEL _Nonnull op, + unsigned arg_size, marg_list _Nullable arg_frame) + OBJC2_UNAVAILABLE; #endif diff --git a/runtime/objc-abi.h b/runtime/objc-abi.h index 7d9e89e..8d861ef 100644 --- a/runtime/objc-abi.h +++ b/runtime/objc-abi.h @@ -46,8 +46,9 @@ /* Runtime startup. */ // Old static initializer. Used by old crt1.o and old bug workarounds. -OBJC_EXPORT void _objcInit(void) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT void +_objcInit(void) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /* Images */ @@ -122,52 +123,78 @@ HasClassProperties: /* Properties */ // Read or write an object property. Not all object properties use these. -OBJC_EXPORT id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -OBJC_EXPORT void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL atomic, signed char shouldCopy) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_getProperty(id _Nullable self, SEL _Nonnull _cmd, + ptrdiff_t offset, BOOL atomic) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); -OBJC_EXPORT void objc_setProperty_atomic(id self, SEL _cmd, id newValue, ptrdiff_t offset) - OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); -OBJC_EXPORT void objc_setProperty_nonatomic(id self, SEL _cmd, id newValue, ptrdiff_t offset) - OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); -OBJC_EXPORT void objc_setProperty_atomic_copy(id self, SEL _cmd, id newValue, ptrdiff_t offset) - OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); -OBJC_EXPORT void objc_setProperty_nonatomic_copy(id self, SEL _cmd, id newValue, ptrdiff_t offset) - OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); +OBJC_EXPORT void +objc_setProperty(id _Nullable self, SEL _Nonnull _cmd, ptrdiff_t offset, + id _Nullable newValue, BOOL atomic, signed char shouldCopy) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_setProperty_atomic(id _Nullable self, SEL _Nonnull _cmd, + id _Nullable newValue, ptrdiff_t offset) + OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_setProperty_nonatomic(id _Nullable self, SEL _Nonnull _cmd, + id _Nullable newValue, ptrdiff_t offset) + OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_setProperty_atomic_copy(id _Nullable self, SEL _Nonnull _cmd, + id _Nullable newValue, ptrdiff_t offset) + OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_setProperty_nonatomic_copy(id _Nullable self, SEL _Nonnull _cmd, + id _Nullable newValue, ptrdiff_t offset) + OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0); // Read or write a non-object property. Not all uses are C structs, // and not all C struct properties use this. -OBJC_EXPORT void objc_copyStruct(void *dest, const void *src, ptrdiff_t size, BOOL atomic, BOOL hasStrong) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +objc_copyStruct(void * _Nonnull dest, const void * _Nonnull src, + ptrdiff_t size, BOOL atomic, BOOL hasStrong) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); // Perform a copy of a C++ object using striped locks. Used by non-POD C++ typed atomic properties. -OBJC_EXPORT void objc_copyCppObjectAtomic(void *dest, const void *src, void (*copyHelper) (void *dest, const void *source)) - OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); +OBJC_EXPORT void +objc_copyCppObjectAtomic(void * _Nonnull dest, const void * _Nonnull src, + void (* _Nonnull copyHelper) + (void * _Nonnull dest, const void * _Nonnull source)) + OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0); /* Classes. */ #if __OBJC2__ -OBJC_EXPORT IMP _objc_empty_vtable - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT IMP _Nonnull _objc_empty_vtable + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); #endif OBJC_EXPORT struct objc_cache _objc_empty_cache - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /* Messages */ #if __OBJC2__ // objc_msgSendSuper2() takes the current search class, not its superclass. -OBJC_EXPORT id objc_msgSendSuper2(struct objc_super *super, SEL op, ...) - OBJC_AVAILABLE(10.6, 2.0, 9.0, 1.0); -OBJC_EXPORT void objc_msgSendSuper2_stret(struct objc_super *super, SEL op,...) - OBJC_AVAILABLE(10.6, 2.0, 9.0, 1.0) +OBJC_EXPORT id _Nullable +objc_msgSendSuper2(struct objc_super * _Nonnull super, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.6, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_msgSendSuper2_stret(struct objc_super * _Nonnull super, + SEL _Nonnull op,...) + OBJC_AVAILABLE(10.6, 2.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; // objc_msgSend_noarg() may be faster for methods with no additional arguments. -OBJC_EXPORT id objc_msgSend_noarg(id self, SEL _cmd) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_msgSend_noarg(id _Nullable self, SEL _Nonnull _cmd) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); #endif #if __OBJC2__ @@ -175,29 +202,42 @@ OBJC_EXPORT id objc_msgSend_noarg(id self, SEL _cmd) // may perform extra sanity checking. // Old objc_msgSendSuper() does not have a debug version; this is OBJC2 only. // *_fixup() do not have debug versions; use non-fixup only for debug mode. -OBJC_EXPORT id objc_msgSend_debug(id self, SEL op, ...) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); -OBJC_EXPORT id objc_msgSendSuper2_debug(struct objc_super *super, SEL op, ...) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); -OBJC_EXPORT void objc_msgSend_stret_debug(id self, SEL op, ...) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0) +OBJC_EXPORT id _Nullable +objc_msgSend_debug(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT id _Nullable +objc_msgSendSuper2_debug(struct objc_super * _Nonnull super, + SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_msgSend_stret_debug(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; -OBJC_EXPORT void objc_msgSendSuper2_stret_debug(struct objc_super *super, SEL op,...) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0) + +OBJC_EXPORT void +objc_msgSendSuper2_stret_debug(struct objc_super * _Nonnull super, + SEL _Nonnull op,...) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; # if defined(__i386__) -OBJC_EXPORT double objc_msgSend_fpret_debug(id self, SEL op, ...) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT double +objc_msgSend_fpret_debug(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); # elif defined(__x86_64__) -OBJC_EXPORT long double objc_msgSend_fpret_debug(id self, SEL op, ...) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT long double +objc_msgSend_fpret_debug(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); # if __STDC_VERSION__ >= 199901L -OBJC_EXPORT _Complex long double objc_msgSend_fp2ret_debug(id self, SEL op, ...) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT _Complex long double +objc_msgSend_fp2ret_debug(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); # else -OBJC_EXPORT void objc_msgSend_fp2ret_debug(id self, SEL op, ...) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT void +objc_msgSend_fp2ret_debug(id _Nullable self, SEL _Nonnull op, ...) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); # endif # endif @@ -219,49 +259,78 @@ OBJC_EXPORT void objc_msgSend_fp2ret_debug(id self, SEL op, ...) // - Red zone is not preserved. // See each architecture's implementation for details. -OBJC_EXPORT void objc_msgLookup(void) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); -OBJC_EXPORT void objc_msgLookupSuper2(void) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); -OBJC_EXPORT void objc_msgLookup_stret(void) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0) +OBJC_EXPORT void +objc_msgLookup(void) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); + +OBJC_EXPORT void +objc_msgLookupSuper2(void) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); + +OBJC_EXPORT void +objc_msgLookup_stret(void) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0) OBJC_ARM64_UNAVAILABLE; -OBJC_EXPORT void objc_msgLookupSuper2_stret(void) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0) + +OBJC_EXPORT void +objc_msgLookupSuper2_stret(void) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0) OBJC_ARM64_UNAVAILABLE; # if defined(__i386__) -OBJC_EXPORT void objc_msgLookup_fpret(void) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); +OBJC_EXPORT void +objc_msgLookup_fpret(void) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); + # elif defined(__x86_64__) -OBJC_EXPORT void objc_msgLookup_fpret(void) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); -OBJC_EXPORT void objc_msgLookup_fp2ret(void) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); +OBJC_EXPORT void +objc_msgLookup_fpret(void) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); + +OBJC_EXPORT void +objc_msgLookup_fp2ret(void) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); # endif #endif #if TARGET_OS_OSX && defined(__x86_64__) // objc_msgSend_fixup() is used for vtable-dispatchable call sites. -OBJC_EXPORT void objc_msgSend_fixup(void) +OBJC_EXPORT void +objc_msgSend_fixup(void) __OSX_DEPRECATED(10.5, 10.8, "fixup dispatch is no longer optimized") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; -OBJC_EXPORT void objc_msgSend_stret_fixup(void) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +OBJC_EXPORT void +objc_msgSend_stret_fixup(void) __OSX_DEPRECATED(10.5, 10.8, "fixup dispatch is no longer optimized") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; -OBJC_EXPORT void objc_msgSendSuper2_fixup(void) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +OBJC_EXPORT void +objc_msgSendSuper2_fixup(void) __OSX_DEPRECATED(10.5, 10.8, "fixup dispatch is no longer optimized") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; -OBJC_EXPORT void objc_msgSendSuper2_stret_fixup(void) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +OBJC_EXPORT void +objc_msgSendSuper2_stret_fixup(void) __OSX_DEPRECATED(10.5, 10.8, "fixup dispatch is no longer optimized") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; -OBJC_EXPORT void objc_msgSend_fpret_fixup(void) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +OBJC_EXPORT void +objc_msgSend_fpret_fixup(void) __OSX_DEPRECATED(10.5, 10.8, "fixup dispatch is no longer optimized") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; -OBJC_EXPORT void objc_msgSend_fp2ret_fixup(void) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +OBJC_EXPORT void +objc_msgSend_fp2ret_fixup(void) __OSX_DEPRECATED(10.5, 10.8, "fixup dispatch is no longer optimized") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; #endif /* C++-compatible exception handling. */ @@ -271,12 +340,12 @@ OBJC_EXPORT void objc_msgSend_fp2ret_fixup(void) #if !defined(__cplusplus) // Vtable for C++ exception typeinfo for Objective-C types. -OBJC_EXPORT const void *objc_ehtype_vtable[] - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const void * _Nullableobjc_ehtype_vtable[] + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); // C++ exception typeinfo for type `id`. OBJC_EXPORT struct objc_typeinfo OBJC_EHTYPE_id - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); #endif @@ -287,16 +356,17 @@ OBJC_EXPORT int __objc_personality_v0(int version, int actions, uint64_t exceptionClass, - struct _Unwind_Exception *exceptionObject, - struct _Unwind_Context *context) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); + struct _Unwind_Exception * _Nonnull exceptionObject, + struct _Unwind_Context * _Nonnull context) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); #endif /* ARC */ -OBJC_EXPORT id objc_retainBlock(id) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_retainBlock(id _Nullable) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); /* Non-pointer isa */ @@ -315,7 +385,7 @@ OBJC_EXPORT id objc_retainBlock(id) // Packed-isa version. This one is used directly by Swift code. // (Class)(isa & (uintptr_t)&objc_absolute_packed_isa_class_mask) == class ptr OBJC_EXPORT const struct { char c; } objc_absolute_packed_isa_class_mask - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); #elif __ARM_ARCH_7K__ >= 2 # define OBJC_HAVE_NONPOINTER_ISA 1 @@ -329,13 +399,13 @@ OBJC_EXPORT const struct { char c; } objc_absolute_packed_isa_class_mask // cls = (Class)isa; // } OBJC_EXPORT const struct { char c; } objc_absolute_indexed_isa_magic_mask - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); OBJC_EXPORT const struct { char c; } objc_absolute_indexed_isa_magic_value - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); OBJC_EXPORT const struct { char c; } objc_absolute_indexed_isa_index_mask - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); OBJC_EXPORT const struct { char c; } objc_absolute_indexed_isa_index_shift - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); #endif diff --git a/runtime/objc-api.h b/runtime/objc-api.h index 42f88e7..fb0e9ea 100644 --- a/runtime/objc-api.h +++ b/runtime/objc-api.h @@ -28,6 +28,7 @@ #include #include #include +#include #ifndef __has_feature # define __has_feature(x) 0 @@ -41,6 +42,27 @@ # define __has_attribute(x) 0 #endif +#if !__has_feature(nullability) +# ifndef _Nullable +# define _Nullable +# endif +# ifndef _Nonnull +# define _Nonnull +# endif +# ifndef _Null_unspecified +# define _Null_unspecified +# endif +#endif + +#ifndef __BRIDGEOS_AVAILABLE +# define __BRIDGEOS_AVAILABLE(v) +#endif +#ifndef __BRIDGEOS_DEPRECATED +# define __BRIDGEOS_DEPRECATED(v1, v2, m) +#endif +#ifndef __BRIDGEOS_UNAVAILABLE +# define __BRIDGEOS_UNAVAILABLE +#endif /* * OBJC_API_VERSION 0 or undef: Tiger and earlier API only @@ -92,9 +114,9 @@ /* OBJC_AVAILABLE: shorthand for all-OS availability */ #if !defined(OBJC_AVAILABLE) -# define OBJC_AVAILABLE(x, i, t, w) \ - __OSX_AVAILABLE(x) __IOS_AVAILABLE(i) \ - __TVOS_AVAILABLE(t) __WATCHOS_AVAILABLE(w) +# define OBJC_AVAILABLE(x, i, t, w, b) \ + __OSX_AVAILABLE(x) __IOS_AVAILABLE(i) __TVOS_AVAILABLE(t) \ + __WATCHOS_AVAILABLE(w) __BRIDGEOS_AVAILABLE(b) #endif @@ -118,7 +140,7 @@ # define OBJC2_UNAVAILABLE \ __OSX_DEPRECATED(10.5, 10.5, "not available in __OBJC2__") \ __IOS_DEPRECATED(2.0, 2.0, "not available in __OBJC2__") \ - __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE + __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE # endif #endif @@ -229,4 +251,12 @@ #define OBJC_OPTIONS(_type, _name) _type _name; enum #endif +#if !defined(OBJC_RETURNS_RETAINED) +# if __OBJC__ && __has_attribute(ns_returns_retained) +# define OBJC_RETURNS_RETAINED __attribute__((ns_returns_retained)) +# else +# define OBJC_RETURNS_RETAINED +# endif +#endif + #endif diff --git a/runtime/objc-auto.h b/runtime/objc-auto.h index 3624af5..37da077 100644 --- a/runtime/objc-auto.h +++ b/runtime/objc-auto.h @@ -24,8 +24,6 @@ #ifndef _OBJC_AUTO_H_ #define _OBJC_AUTO_H_ -#pragma GCC system_header - #include #include #include @@ -57,7 +55,7 @@ enum { OBJC_EXHAUSTIVE_COLLECTION = (3 << 0), OBJC_COLLECT_IF_NEEDED = (1 << 3), - OBJC_WAIT_UNTIL_DONE = (1 << 4), + OBJC_WAIT_UNTIL_DONE = (1 << 4) }; enum { @@ -71,65 +69,65 @@ enum { /* Out-of-line declarations */ OBJC_EXPORT void objc_collect(unsigned long options) - __OSX_DEPRECATED(10.6, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.6, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT BOOL objc_collectingEnabled(void) - __OSX_DEPRECATED(10.5, 10.8, "it always returns NO") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.5, 10.8, "it always returns NO") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT malloc_zone_t *objc_collectableZone(void) - __OSX_DEPRECATED(10.7, 10.8, "it always returns nil") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.7, 10.8, "it always returns nil") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void objc_setCollectionThreshold(size_t threshold) - __OSX_DEPRECATED(10.5, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.5, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void objc_setCollectionRatio(size_t ratio) - __OSX_DEPRECATED(10.5, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.5, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation) - __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtr instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; + __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtr instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; OBJC_EXPORT BOOL objc_atomicCompareAndSwapPtrBarrier(id predicate, id replacement, volatile id *objectLocation) - __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtrBarrier instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; + __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtrBarrier instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(id predicate, id replacement, volatile id *objectLocation) - __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtr instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; + __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtr instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobalBarrier(id predicate, id replacement, volatile id *objectLocation) - __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtrBarrier instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; + __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtrBarrier instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; OBJC_EXPORT BOOL objc_atomicCompareAndSwapInstanceVariable(id predicate, id replacement, volatile id *objectLocation) - __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtr instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; + __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtr instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; OBJC_EXPORT BOOL objc_atomicCompareAndSwapInstanceVariableBarrier(id predicate, id replacement, volatile id *objectLocation) - __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtrBarrier instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; + __OSX_DEPRECATED(10.6, 10.8, "use OSAtomicCompareAndSwapPtrBarrier instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; OBJC_EXPORT id objc_assign_strongCast(id val, id *dest) - __OSX_DEPRECATED(10.4, 10.8, "use a simple assignment instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.4, 10.8, "use a simple assignment instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT id objc_assign_global(id val, id *dest) - __OSX_DEPRECATED(10.4, 10.8, "use a simple assignment instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.4, 10.8, "use a simple assignment instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT id objc_assign_threadlocal(id val, id *dest) - __OSX_DEPRECATED(10.7, 10.8, "use a simple assignment instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.7, 10.8, "use a simple assignment instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT id objc_assign_ivar(id value, id dest, ptrdiff_t offset) - __OSX_DEPRECATED(10.4, 10.8, "use a simple assignment instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.4, 10.8, "use a simple assignment instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void *objc_memmove_collectable(void *dst, const void *src, size_t size) - __OSX_DEPRECATED(10.4, 10.8, "use memmove instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.4, 10.8, "use memmove instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT id objc_read_weak(id *location) - __OSX_DEPRECATED(10.5, 10.8, "use a simple read instead, or convert to zeroing __weak") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.5, 10.8, "use a simple read instead, or convert to zeroing __weak") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT id objc_assign_weak(id value, id *location) - __OSX_DEPRECATED(10.5, 10.8, "use a simple assignment instead, or convert to zeroing __weak") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.5, 10.8, "use a simple assignment instead, or convert to zeroing __weak") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void objc_registerThreadWithCollector(void) - __OSX_DEPRECATED(10.6, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.6, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void objc_unregisterThreadWithCollector(void) - __OSX_DEPRECATED(10.6, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.6, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void objc_assertRegisteredThreadWithCollector(void) - __OSX_DEPRECATED(10.6, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.6, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void objc_clear_stack(unsigned long options) - __OSX_DEPRECATED(10.5, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.5, 10.8, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT BOOL objc_is_finalized(void *ptr) - __OSX_DEPRECATED(10.4, 10.8, "it always returns NO") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.4, 10.8, "it always returns NO") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void objc_finalizeOnMainThread(Class cls) - __OSX_DEPRECATED(10.5, 10.5, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.5, 10.5, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT BOOL objc_collecting_enabled(void) - __OSX_DEPRECATED(10.4, 10.5, "it always returns NO") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.4, 10.5, "it always returns NO") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void objc_set_collection_threshold(size_t threshold) - __OSX_DEPRECATED(10.4, 10.5, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.4, 10.5, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void objc_set_collection_ratio(size_t ratio) - __OSX_DEPRECATED(10.4, 10.5, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.4, 10.5, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void objc_start_collector_thread(void) - __OSX_DEPRECATED(10.4, 10.5, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.4, 10.5, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT void objc_startCollectorThread(void) - __OSX_DEPRECATED(10.5, 10.7, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.5, 10.7, "it does nothing") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; OBJC_EXPORT id objc_allocate_object(Class cls, int extra) - __OSX_DEPRECATED(10.4, 10.4, "use class_createInstance instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __OSX_DEPRECATED(10.4, 10.4, "use class_createInstance instead") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; /* !defined(OBJC_NO_GC) */ @@ -199,7 +197,7 @@ static OBJC_INLINE id objc_assign_threadlocal(id val, id *dest) OBJC_GC_DEPRECATED("use a simple assignment instead") static OBJC_INLINE id objc_assign_ivar(id val, id dest, ptrdiff_t offset) - { return (*(id*)((char *)dest+offset) = val); } + { return (*(id*)((intptr_t)(char *)dest+offset) = val); } OBJC_GC_DEPRECATED("use a simple read instead, or convert to zeroing __weak") static OBJC_INLINE id objc_read_weak(id *location) @@ -235,10 +233,10 @@ static OBJC_INLINE void objc_start_collector_thread(void) { } extern id objc_allocate_object(Class cls, int extra) UNAVAILABLE_ATTRIBUTE; #else OBJC_EXPORT id class_createInstance(Class cls, size_t extraBytes) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); OBJC_GC_DEPRECATED("use class_createInstance instead") static OBJC_INLINE id objc_allocate_object(Class cls, int extra) - { return class_createInstance(cls, extra); } + { return class_createInstance(cls, (size_t)extra); } #endif OBJC_GC_DEPRECATED("it does nothing") diff --git a/runtime/objc-block-trampolines.mm b/runtime/objc-block-trampolines.mm index ccde02a..6ef5fcf 100644 --- a/runtime/objc-block-trampolines.mm +++ b/runtime/objc-block-trampolines.mm @@ -217,59 +217,40 @@ static TrampolineBlockPagePair *_allocateTrampolinesAndData(ArgumentMode aMode) TrampolineBlockPagePair *headPagePair = headPagePairs[aMode]; - if (headPagePair) { - assert(headPagePair->nextAvailablePage == nil); - } + assert(headPagePair == nil || headPagePair->nextAvailablePage == nil); kern_return_t result; - for (int i = 0; i < 5; i++) { - result = vm_allocate(mach_task_self(), &dataAddress, - PAGE_MAX_SIZE * 2, - TRUE | VM_MAKE_TAG(VM_MEMORY_FOUNDATION)); - if (result != KERN_SUCCESS) { - mach_error("vm_allocate failed", result); - return nil; - } + result = vm_allocate(mach_task_self(), &dataAddress, PAGE_MAX_SIZE * 2, + VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_FOUNDATION)); + if (result != KERN_SUCCESS) { + _objc_fatal("vm_allocate trampolines failed (%d)", result); + } - vm_address_t codeAddress = dataAddress + PAGE_MAX_SIZE; - result = vm_deallocate(mach_task_self(), codeAddress, PAGE_MAX_SIZE); - if (result != KERN_SUCCESS) { - mach_error("vm_deallocate failed", result); - return nil; - } + vm_address_t codeAddress = dataAddress + PAGE_MAX_SIZE; - uintptr_t codePage; - switch(aMode) { - case ReturnValueInRegisterArgumentMode: - codePage = a1a2_tramphead(); - break; + uintptr_t codePage; + switch(aMode) { + case ReturnValueInRegisterArgumentMode: + codePage = a1a2_tramphead(); + break; #if SUPPORT_STRET - case ReturnValueOnStackArgumentMode: - codePage = a2a3_tramphead(); - break; + case ReturnValueOnStackArgumentMode: + codePage = a2a3_tramphead(); + break; #endif - default: - _objc_fatal("unknown return mode %d", (int)aMode); - break; - } - vm_prot_t currentProtection, maxProtection; - result = vm_remap(mach_task_self(), &codeAddress, PAGE_MAX_SIZE, - 0, FALSE, mach_task_self(), codePage, TRUE, - ¤tProtection, &maxProtection, VM_INHERIT_SHARE); - if (result != KERN_SUCCESS) { - result = vm_deallocate(mach_task_self(), - dataAddress, PAGE_MAX_SIZE); - if (result != KERN_SUCCESS) { - mach_error("vm_deallocate for retry failed.", result); - return nil; - } - } else { - break; - } + default: + _objc_fatal("unknown return mode %d", (int)aMode); + break; } + vm_prot_t currentProtection, maxProtection; + result = vm_remap(mach_task_self(), &codeAddress, PAGE_MAX_SIZE, + 0, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, + mach_task_self(), codePage, TRUE, + ¤tProtection, &maxProtection, VM_INHERIT_SHARE); if (result != KERN_SUCCESS) { - return nil; + // vm_deallocate(mach_task_self(), dataAddress, PAGE_MAX_SIZE * 2); + _objc_fatal("vm_remap trampolines failed (%d)", result); } TrampolineBlockPagePair *pagePair = (TrampolineBlockPagePair *) dataAddress; @@ -279,9 +260,9 @@ static TrampolineBlockPagePair *_allocateTrampolinesAndData(ArgumentMode aMode) if (headPagePair) { TrampolineBlockPagePair *lastPagePair = headPagePair; - while(lastPagePair->nextPagePair) + while(lastPagePair->nextPagePair) { lastPagePair = lastPagePair->nextPagePair; - + } lastPagePair->nextPagePair = pagePair; headPagePairs[aMode]->nextAvailablePage = pagePair; } else { diff --git a/runtime/objc-env.h b/runtime/objc-env.h index 7eb0afa..5ff3382 100644 --- a/runtime/objc-env.h +++ b/runtime/objc-env.h @@ -40,3 +40,4 @@ OPTION( DisableVtables, OBJC_DISABLE_VTABLES, "disable vtab OPTION( DisablePreopt, OBJC_DISABLE_PREOPTIMIZATION, "disable preoptimization courtesy of dyld shared cache") OPTION( DisableTaggedPointers, OBJC_DISABLE_TAGGED_POINTERS, "disable tagged pointer optimization of NSNumber et al.") OPTION( DisableNonpointerIsa, OBJC_DISABLE_NONPOINTER_ISA, "disable non-pointer isa fields") +OPTION( DisableInitializeForkSafety, OBJC_DISABLE_INITIALIZE_FORK_SAFETY, "disable safety checks for +initialize after fork") diff --git a/runtime/objc-exception.h b/runtime/objc-exception.h index c67b92a..d6cbb7e 100644 --- a/runtime/objc-exception.h +++ b/runtime/objc-exception.h @@ -31,51 +31,71 @@ // compiler reserves a setjmp buffer + 4 words as localExceptionData -OBJC_EXPORT void objc_exception_throw(id exception) +OBJC_EXPORT void +objc_exception_throw(id _Nonnull exception) __OSX_AVAILABLE(10.3) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; -OBJC_EXPORT void objc_exception_try_enter(void *localExceptionData) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +OBJC_EXPORT void +objc_exception_try_enter(void * _Nonnull localExceptionData) __OSX_AVAILABLE(10.3) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; -OBJC_EXPORT void objc_exception_try_exit(void *localExceptionData) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +OBJC_EXPORT void +objc_exception_try_exit(void * _Nonnull localExceptionData) __OSX_AVAILABLE(10.3) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; -OBJC_EXPORT id objc_exception_extract(void *localExceptionData) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +OBJC_EXPORT id _Nonnull +objc_exception_extract(void * _Nonnull localExceptionData) __OSX_AVAILABLE(10.3) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; -OBJC_EXPORT int objc_exception_match(Class exceptionClass, id exception) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +OBJC_EXPORT int objc_exception_match(Class _Nonnull exceptionClass, + id _Nonnull exception) __OSX_AVAILABLE(10.3) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; typedef struct { int version; - void (*throw_exc)(id); // version 0 - void (*try_enter)(void *); // version 0 - void (*try_exit)(void *); // version 0 - id (*extract)(void *); // version 0 - int (*match)(Class, id); // version 0 + void (* _Nonnull throw_exc)(id _Nonnull); // version 0 + void (* _Nonnull try_enter)(void * _Nonnull); // version 0 + void (* _Nonnull try_exit)(void * _Nonnull); // version 0 + id _Nonnull (* _Nonnull extract)(void * _Nonnull); // version 0 + int (* _Nonnull match)(Class _Nonnull, id _Nonnull); // version 0 } objc_exception_functions_t; // get table; version tells how many -OBJC_EXPORT void objc_exception_get_functions(objc_exception_functions_t *table) +OBJC_EXPORT void +objc_exception_get_functions(objc_exception_functions_t * _Nullable table) __OSX_AVAILABLE(10.3) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; // set table -OBJC_EXPORT void objc_exception_set_functions(objc_exception_functions_t *table) +OBJC_EXPORT void +objc_exception_set_functions(objc_exception_functions_t * _Nullable table) __OSX_AVAILABLE(10.3) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; // !__OBJC2__ #else // __OBJC2__ -typedef id (*objc_exception_preprocessor)(id exception); -typedef int (*objc_exception_matcher)(Class catch_type, id exception); -typedef void (*objc_uncaught_exception_handler)(id exception); -typedef void (*objc_exception_handler)(id unused, void *context); +typedef id _Nonnull (*objc_exception_preprocessor)(id _Nonnull exception); +typedef int (*objc_exception_matcher)(Class _Nonnull catch_type, + id _Nonnull exception); +typedef void (*objc_uncaught_exception_handler)(id _Null_unspecified /* _Nonnull */ exception); +typedef void (*objc_exception_handler)(id _Nullable unused, + void * _Nullable context); /** * Throw a runtime exception. This function is inserted by the compiler @@ -83,31 +103,51 @@ typedef void (*objc_exception_handler)(id unused, void *context); * * @param exception The exception to be thrown. */ -OBJC_EXPORT void objc_exception_throw(id exception) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -OBJC_EXPORT void objc_exception_rethrow(void) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -OBJC_EXPORT id objc_begin_catch(void *exc_buf) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -OBJC_EXPORT void objc_end_catch(void) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -OBJC_EXPORT void objc_terminate(void) - OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); - -OBJC_EXPORT objc_exception_preprocessor objc_setExceptionPreprocessor(objc_exception_preprocessor fn) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -OBJC_EXPORT objc_exception_matcher objc_setExceptionMatcher(objc_exception_matcher fn) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -OBJC_EXPORT objc_uncaught_exception_handler objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler fn) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +objc_exception_throw(id _Nonnull exception) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_exception_rethrow(void) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT id _Nonnull +objc_begin_catch(void * _Nonnull exc_buf) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_end_catch(void) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT void +objc_terminate(void) + OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT objc_exception_preprocessor _Nonnull +objc_setExceptionPreprocessor(objc_exception_preprocessor _Nonnull fn) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT objc_exception_matcher _Nonnull +objc_setExceptionMatcher(objc_exception_matcher _Nonnull fn) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT objc_uncaught_exception_handler _Nonnull +objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler _Nonnull fn) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); // Not for iOS. -OBJC_EXPORT uintptr_t objc_addExceptionHandler(objc_exception_handler fn, void *context) +OBJC_EXPORT uintptr_t +objc_addExceptionHandler(objc_exception_handler _Nonnull fn, + void * _Nullable context) __OSX_AVAILABLE(10.5) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; -OBJC_EXPORT void objc_removeExceptionHandler(uintptr_t token) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +OBJC_EXPORT void +objc_removeExceptionHandler(uintptr_t token) __OSX_AVAILABLE(10.5) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; // __OBJC2__ #endif diff --git a/runtime/objc-gdb.h b/runtime/objc-gdb.h index 0c01590..9177775 100644 --- a/runtime/objc-gdb.h +++ b/runtime/objc-gdb.h @@ -47,16 +47,17 @@ __BEGIN_DECLS **********************************************************************/ // Return cls if it's a valid class, or crash. -OBJC_EXPORT Class gdb_class_getClass(Class cls) +OBJC_EXPORT Class _Nonnull +gdb_class_getClass(Class _Nonnull cls) #if __OBJC2__ - OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0); + OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0); #else - OBJC_AVAILABLE(10.7, 3.1, 9.0, 1.0); + OBJC_AVAILABLE(10.7, 3.1, 9.0, 1.0, 2.0); #endif // Same as gdb_class_getClass(object_getClass(cls)). -OBJC_EXPORT Class gdb_object_getClass(id obj) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT Class _Nonnull gdb_object_getClass(id _Nullable obj) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /*********************************************************************** @@ -66,15 +67,16 @@ OBJC_EXPORT Class gdb_object_getClass(id obj) #if __OBJC2__ // Maps class name to Class, for in-use classes only. NXStrValueMapPrototype. -OBJC_EXPORT NXMapTable *gdb_objc_realized_classes - OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0); +OBJC_EXPORT NXMapTable * _Nullable gdb_objc_realized_classes + OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0); #else // Hashes Classes, for all known classes. Custom prototype. -OBJC_EXPORT NXHashTable *_objc_debug_class_hash +OBJC_EXPORT NXHashTable * _Nullable _objc_debug_class_hash __OSX_AVAILABLE(10.2) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; #endif @@ -88,14 +90,14 @@ OBJC_EXPORT NXHashTable *_objc_debug_class_hash // Extract isa pointer from an isa field. // (Class)(isa & mask) == class pointer OBJC_EXPORT const uintptr_t objc_debug_isa_class_mask - OBJC_AVAILABLE(10.10, 7.0, 9.0, 1.0); + OBJC_AVAILABLE(10.10, 7.0, 9.0, 1.0, 2.0); // Extract magic cookie from an isa field. // (isa & magic_mask) == magic_value OBJC_EXPORT const uintptr_t objc_debug_isa_magic_mask - OBJC_AVAILABLE(10.10, 7.0, 9.0, 1.0); + OBJC_AVAILABLE(10.10, 7.0, 9.0, 1.0, 2.0); OBJC_EXPORT const uintptr_t objc_debug_isa_magic_value - OBJC_AVAILABLE(10.10, 7.0, 9.0, 1.0); + OBJC_AVAILABLE(10.10, 7.0, 9.0, 1.0, 2.0); // Use indexed ISAs for targets which store index of the class in the ISA. // This index can be used to index the array of classes. @@ -109,7 +111,7 @@ OBJC_EXPORT const uintptr_t objc_debug_indexed_isa_index_shift; // And then we can use that index to get the class from this array. Note // the size is provided so that clients can ensure the index they get is in // bounds and not read off the end of the array. -OBJC_EXPORT Class objc_indexed_classes[]; +OBJC_EXPORT Class _Nullable objc_indexed_classes[]; // When we don't have enough bits to store a class*, we can instead store an // index in to this array. Classes are added here when they are realized. @@ -121,6 +123,20 @@ OBJC_EXPORT uintptr_t objc_indexed_classes_count; #endif +/*********************************************************************** +* Class structure decoding +**********************************************************************/ +#if __OBJC2__ + +// Mask for the pointer from class struct to class rw data. +// Other bits may be used for flags. +// Use 0x00007ffffffffff8UL or 0xfffffffcUL when this variable is unavailable. +OBJC_EXPORT const uintptr_t objc_debug_class_rw_data_mask + OBJC_AVAILABLE(10.13, 11.0, 11.0, 4.0, 2.0); + +#endif + + /*********************************************************************** * Tagged pointer decoding **********************************************************************/ @@ -130,24 +146,24 @@ OBJC_EXPORT uintptr_t objc_indexed_classes_count; // if (obj & mask) obj is a tagged pointer object OBJC_EXPORT uintptr_t objc_debug_taggedpointer_mask - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); // tag_slot = (obj >> slot_shift) & slot_mask OBJC_EXPORT unsigned int objc_debug_taggedpointer_slot_shift - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); OBJC_EXPORT uintptr_t objc_debug_taggedpointer_slot_mask - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); // class = classes[tag_slot] -OBJC_EXPORT Class objc_debug_taggedpointer_classes[] - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); +OBJC_EXPORT Class _Nullable objc_debug_taggedpointer_classes[] + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); // payload = (obj << payload_lshift) >> payload_rshift // Payload signedness is determined by the signedness of the right-shift. OBJC_EXPORT unsigned int objc_debug_taggedpointer_payload_lshift - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); OBJC_EXPORT unsigned int objc_debug_taggedpointer_payload_rshift - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); // Extended tagged pointers (255 classes, 52-bit payload). @@ -159,24 +175,24 @@ OBJC_EXPORT unsigned int objc_debug_taggedpointer_payload_rshift // if (ext_mask != 0 && (obj & ext_mask) == ext_mask) // obj is a ext tagged pointer object OBJC_EXPORT uintptr_t objc_debug_taggedpointer_ext_mask - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); // ext_tag_slot = (obj >> ext_slot_shift) & ext_slot_mask OBJC_EXPORT unsigned int objc_debug_taggedpointer_ext_slot_shift - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); OBJC_EXPORT uintptr_t objc_debug_taggedpointer_ext_slot_mask - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); // class = ext_classes[ext_tag_slot] -OBJC_EXPORT Class objc_debug_taggedpointer_ext_classes[] - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); +OBJC_EXPORT Class _Nullable objc_debug_taggedpointer_ext_classes[] + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); // payload = (obj << ext_payload_lshift) >> ext_payload_rshift // Payload signedness is determined by the signedness of the right-shift. OBJC_EXPORT unsigned int objc_debug_taggedpointer_ext_payload_lshift - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); OBJC_EXPORT unsigned int objc_debug_taggedpointer_ext_payload_rshift - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); #endif @@ -211,7 +227,7 @@ struct objc_messenger_breakpoint { OBJC_EXPORT struct objc_messenger_breakpoint gdb_objc_messenger_breakpoints[] - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); #endif diff --git a/runtime/objc-initialize.mm b/runtime/objc-initialize.mm index 0f410b6..80491bb 100644 --- a/runtime/objc-initialize.mm +++ b/runtime/objc-initialize.mm @@ -280,8 +280,8 @@ static void _finishInitializing(Class cls, Class supercls) assert(!supercls || supercls->isInitialized()); if (PrintInitializing) { - _objc_inform("INITIALIZE: %s is fully +initialized", - cls->nameForLogging()); + _objc_inform("INITIALIZE: thread %p: %s is fully +initialized", + pthread_self(), cls->nameForLogging()); } // mark this class as fully +initialized @@ -323,8 +323,10 @@ static void _finishInitializingAfter(Class cls, Class supercls) classInitLock.assertLocked(); if (PrintInitializing) { - _objc_inform("INITIALIZE: %s waiting for superclass +[%s initialize]", - cls->nameForLogging(), supercls->nameForLogging()); + _objc_inform("INITIALIZE: thread %p: class %s will be marked as fully " + "+initialized after superclass +[%s initialize] completes", + pthread_self(), cls->nameForLogging(), + supercls->nameForLogging()); } if (!pendingInitializeMap) { @@ -352,6 +354,11 @@ void callInitialize(Class cls) void waitForInitializeToComplete(Class cls) { + if (PrintInitializing) { + _objc_inform("INITIALIZE: thread %p: blocking until +[%s initialize] " + "completes", pthread_self(), cls->nameForLogging()); + } + monitor_locker_t lock(classInitLock); while (!cls->isInitialized()) { classInitLock.wait(); @@ -367,6 +374,109 @@ void callInitialize(Class cls) } +/*********************************************************************** +* classHasTrivialInitialize +* Returns true if the class has no +initialize implementation or +* has a +initialize implementation that looks empty. +* Any root class +initialize implemetation is assumed to be trivial. +**********************************************************************/ +static bool classHasTrivialInitialize(Class cls) +{ + if (cls->isRootClass() || cls->isRootMetaclass()) return true; + + Class rootCls = cls->ISA()->ISA()->superclass; + + IMP rootImp = lookUpImpOrNil(rootCls->ISA(), SEL_initialize, rootCls, + NO/*initialize*/, YES/*cache*/, NO/*resolver*/); + IMP imp = lookUpImpOrNil(cls->ISA(), SEL_initialize, cls, + NO/*initialize*/, YES/*cache*/, NO/*resolver*/); + return (imp == nil || imp == (IMP)&objc_noop_imp || imp == rootImp); +} + + +/*********************************************************************** +* lockAndFinishInitializing +* Mark a class as finished initializing and notify waiters, or queue for later. +* If the superclass is also done initializing, then update +* the info bits and notify waiting threads. +* If not, update them later. (This can happen if this +initialize +* was itself triggered from inside a superclass +initialize.) +**********************************************************************/ +static void lockAndFinishInitializing(Class cls, Class supercls) +{ + monitor_locker_t lock(classInitLock); + if (!supercls || supercls->isInitialized()) { + _finishInitializing(cls, supercls); + } else { + _finishInitializingAfter(cls, supercls); + } +} + + +/*********************************************************************** +* performForkChildInitialize +* +initialize after fork() is problematic. It's possible for the +* fork child process to call some +initialize that would deadlock waiting +* for another +initialize in the parent process. +* We wouldn't know how much progress it made therein, so we can't +* act as if +initialize completed nor can we restart +initialize +* from scratch. +* +* Instead we proceed introspectively. If the class has some +* +initialize implementation, we halt. If the class has no +* +initialize implementation of its own, we continue. Root +* class +initialize is assumed to be empty if it exists. +* +* We apply this rule even if the child's +initialize does not appear +* to be blocked by anything. This prevents races wherein the +initialize +* deadlock only rarely hits. Instead we disallow it even when we "won" +* the race. +* +* Exception: processes that are single-threaded when fork() is called +* have no restrictions on +initialize in the child. Examples: sshd and httpd. +* +* Classes that wish to implement +initialize and be callable after +* fork() must use an atfork() handler to provoke +initialize in fork prepare. +**********************************************************************/ + +// Called before halting when some +initialize +// method can't be called after fork(). +BREAKPOINT_FUNCTION( + void objc_initializeAfterForkError(Class cls) +); + +void performForkChildInitialize(Class cls, Class supercls) +{ + if (classHasTrivialInitialize(cls)) { + if (PrintInitializing) { + _objc_inform("INITIALIZE: thread %p: skipping trivial +[%s " + "initialize] in fork() child process", + pthread_self(), cls->nameForLogging()); + } + lockAndFinishInitializing(cls, supercls); + } + else { + if (PrintInitializing) { + _objc_inform("INITIALIZE: thread %p: refusing to call +[%s " + "initialize] in fork() child process because " + "it may have been in progress when fork() was called", + pthread_self(), cls->nameForLogging()); + } + _objc_inform_now_and_on_crash + ("+[%s initialize] may have been in progress in another thread " + "when fork() was called.", + cls->nameForLogging()); + objc_initializeAfterForkError(cls); + _objc_fatal + ("+[%s initialize] may have been in progress in another thread " + "when fork() was called. We cannot safely call it or " + "ignore it in the fork() child process. Crashing instead. " + "Set a breakpoint on objc_initializeAfterForkError to debug.", + cls->nameForLogging()); + } +} + + /*********************************************************************** * class_initialize. Send the '+initialize' message on demand to any * uninitialized class. Force initialization of superclasses first. @@ -399,44 +509,52 @@ void _class_initialize(Class cls) // Record that we're initializing this class so we can message it. _setThisThreadIsInitializingClass(cls); + + if (MultithreadedForkChild) { + // LOL JK we don't really call +initialize methods after fork(). + performForkChildInitialize(cls, supercls); + return; + } // Send the +initialize message. // Note that +initialize is sent to the superclass (again) if // this class doesn't implement +initialize. 2157218 if (PrintInitializing) { - _objc_inform("INITIALIZE: calling +[%s initialize]", - cls->nameForLogging()); + _objc_inform("INITIALIZE: thread %p: calling +[%s initialize]", + pthread_self(), cls->nameForLogging()); } // Exceptions: A +initialize call that throws an exception // is deemed to be a complete and successful +initialize. - @try { + // + // Only __OBJC2__ adds these handlers. !__OBJC2__ has a + // bootstrapping problem of this versus CF's call to + // objc_exception_set_functions(). +#if __OBJC2__ + @try +#endif + { callInitialize(cls); if (PrintInitializing) { - _objc_inform("INITIALIZE: finished +[%s initialize]", - cls->nameForLogging()); + _objc_inform("INITIALIZE: thread %p: finished +[%s initialize]", + pthread_self(), cls->nameForLogging()); } } +#if __OBJC2__ @catch (...) { if (PrintInitializing) { - _objc_inform("INITIALIZE: +[%s initialize] threw an exception", - cls->nameForLogging()); + _objc_inform("INITIALIZE: thread %p: +[%s initialize] " + "threw an exception", + pthread_self(), cls->nameForLogging()); } @throw; } - @finally { - // Done initializing. - // If the superclass is also done initializing, then update - // the info bits and notify waiting threads. - // If not, update them later. (This can happen if this +initialize - // was itself triggered from inside a superclass +initialize.) - monitor_locker_t lock(classInitLock); - if (!supercls || supercls->isInitialized()) { - _finishInitializing(cls, supercls); - } else { - _finishInitializingAfter(cls, supercls); - } + @finally +#endif + { + // Done initializing. + lockAndFinishInitializing(cls, supercls); } return; } @@ -450,9 +568,14 @@ void _class_initialize(Class cls) // before blocking. if (_thisThreadIsInitializingClass(cls)) { return; - } else { + } else if (!MultithreadedForkChild) { waitForInitializeToComplete(cls); return; + } else { + // We're on the child side of fork(), facing a class that + // was initializing by some other thread when fork() was called. + _setThisThreadIsInitializingClass(cls); + performForkChildInitialize(cls, supercls); } } diff --git a/runtime/objc-internal.h b/runtime/objc-internal.h index 6a28c59..fbd8820 100644 --- a/runtime/objc-internal.h +++ b/runtime/objc-internal.h @@ -59,8 +59,10 @@ __BEGIN_DECLS // Returns nil if a class with the same name already exists. // Returns nil if the superclass is under construction. // Call objc_registerClassPair() when you are done. -OBJC_EXPORT Class objc_initializeClassPair(Class superclass, const char *name, Class cls, Class metacls) - OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0); +OBJC_EXPORT Class _Nullable +objc_initializeClassPair(Class _Nullable superclass, const char * _Nonnull name, + Class _Nonnull cls, Class _Nonnull metacls) + OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0); // Class and metaclass construction from a compiler-generated memory image. // cls and cls->isa must each be OBJC_MAX_CLASS_SIZE bytes. @@ -72,90 +74,122 @@ OBJC_EXPORT Class objc_initializeClassPair(Class superclass, const char *name, C // Do not call objc_registerClassPair(). #if __OBJC2__ struct objc_image_info; -OBJC_EXPORT Class objc_readClassPair(Class cls, - const struct objc_image_info *info) - OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0); +OBJC_EXPORT Class _Nullable +objc_readClassPair(Class _Nonnull cls, + const struct objc_image_info * _Nonnull info) + OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0, 2.0); #endif // Batch object allocation using malloc_zone_batch_malloc(). -OBJC_EXPORT unsigned class_createInstances(Class cls, size_t extraBytes, - id *results, unsigned num_requested) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0) +OBJC_EXPORT unsigned +class_createInstances(Class _Nullable cls, size_t extraBytes, + id _Nonnull * _Nonnull results, unsigned num_requested) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0) OBJC_ARC_UNAVAILABLE; // Get the isa pointer written into objects just before being freed. -OBJC_EXPORT Class _objc_getFreedObjectClass(void) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT Class _Nonnull +_objc_getFreedObjectClass(void) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); // env NSObjCMessageLoggingEnabled -OBJC_EXPORT void instrumentObjcMessageSends(BOOL flag) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT void +instrumentObjcMessageSends(BOOL flag) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); // Initializer called by libSystem -OBJC_EXPORT void _objc_init(void) +OBJC_EXPORT void +_objc_init(void) #if __OBJC2__ - OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); + OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0); #else - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); #endif // fork() safety called by libSystem -OBJC_EXPORT void _objc_atfork_prepare(void) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); -OBJC_EXPORT void _objc_atfork_parent(void) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); -OBJC_EXPORT void _objc_atfork_child(void) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); +OBJC_EXPORT void +_objc_atfork_prepare(void) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); + +OBJC_EXPORT void +_objc_atfork_parent(void) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); + +OBJC_EXPORT void +_objc_atfork_child(void) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); // Return YES if GC is on and `object` is a GC allocation. -OBJC_EXPORT BOOL objc_isAuto(id object) +OBJC_EXPORT BOOL +objc_isAuto(id _Nullable object) __OSX_DEPRECATED(10.4, 10.8, "it always returns NO") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; // GC startup callback from Foundation -OBJC_EXPORT malloc_zone_t *objc_collect_init(int (*callback)(void)) +OBJC_EXPORT malloc_zone_t * _Nullable +objc_collect_init(int (* _Nonnull callback)(void)) __OSX_DEPRECATED(10.4, 10.8, "it does nothing") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; // Plainly-implemented GC barriers. Rosetta used to use these. -OBJC_EXPORT id objc_assign_strongCast_generic(id value, id *dest) +OBJC_EXPORT id _Nullable +objc_assign_strongCast_generic(id _Nullable value, id _Nullable * _Nonnull dest) UNAVAILABLE_ATTRIBUTE; -OBJC_EXPORT id objc_assign_global_generic(id value, id *dest) + +OBJC_EXPORT id _Nullable +objc_assign_global_generic(id _Nullable value, id _Nullable * _Nonnull dest) UNAVAILABLE_ATTRIBUTE; -OBJC_EXPORT id objc_assign_threadlocal_generic(id value, id *dest) + +OBJC_EXPORT id _Nullable +objc_assign_threadlocal_generic(id _Nullable value, + id _Nullable * _Nonnull dest) UNAVAILABLE_ATTRIBUTE; -OBJC_EXPORT id objc_assign_ivar_generic(id value, id dest, ptrdiff_t offset) + +OBJC_EXPORT id _Nullable +objc_assign_ivar_generic(id _Nullable value, id _Nonnull dest, ptrdiff_t offset) UNAVAILABLE_ATTRIBUTE; // GC preflight for an app executable. // 1: some slice requires GC // 0: no slice requires GC // -1: I/O or file format error -OBJC_EXPORT int objc_appRequiresGC(int fd) +OBJC_EXPORT int +objc_appRequiresGC(int fd) __OSX_AVAILABLE(10.11) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; // Install missing-class callback. Used by the late unlamented ZeroLink. -OBJC_EXPORT void _objc_setClassLoader(BOOL (*newClassLoader)(const char *)) OBJC2_UNAVAILABLE; +OBJC_EXPORT void +_objc_setClassLoader(BOOL (* _Nonnull newClassLoader)(const char * _Nonnull)) + OBJC2_UNAVAILABLE; // Install handler for allocation failures. // Handler may abort, or throw, or provide an object to return. -OBJC_EXPORT void _objc_setBadAllocHandler(id (*newHandler)(Class isa)) - OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); +OBJC_EXPORT void +_objc_setBadAllocHandler(id _Nullable (* _Nonnull newHandler) + (Class _Nullable isa)) + OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0); // This can go away when AppKit stops calling it (rdar://7811851) #if __OBJC2__ -OBJC_EXPORT void objc_setMultithreaded (BOOL flag) +OBJC_EXPORT void +objc_setMultithreaded (BOOL flag) __OSX_DEPRECATED(10.0, 10.5, "multithreading is always available") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; #endif // Used by ExceptionHandling.framework #if !__OBJC2__ -OBJC_EXPORT void _objc_error(id rcv, const char *fmt, va_list args) +OBJC_EXPORT void +_objc_error(id _Nullable rcv, const char * _Nonnull fmt, va_list args) __attribute__((noreturn)) __OSX_DEPRECATED(10.0, 10.5, "use other logging facilities instead") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; #endif @@ -210,44 +244,46 @@ _objc_taggedPointersEnabled(void); // Register a class for a tagged pointer tag. // Aborts if the tag is invalid or already in use. -OBJC_EXPORT void _objc_registerTaggedPointerClass(objc_tag_index_t tag, Class cls) - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); +OBJC_EXPORT void +_objc_registerTaggedPointerClass(objc_tag_index_t tag, Class _Nonnull cls) + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); // Returns the registered class for the given tag. // Returns nil if the tag is valid but has no registered class. // Aborts if the tag is invalid. -OBJC_EXPORT Class _objc_getClassForTag(objc_tag_index_t tag) - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); +OBJC_EXPORT Class _Nullable +_objc_getClassForTag(objc_tag_index_t tag) + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); // Create a tagged pointer object with the given tag and payload. // Assumes the tag is valid. // Assumes tagged pointers are enabled. // The payload will be silently truncated to fit. -static inline void * +static inline void * _Nonnull _objc_makeTaggedPointer(objc_tag_index_t tag, uintptr_t payload); // Return true if ptr is a tagged pointer object. // Does not check the validity of ptr's class. static inline bool -_objc_isTaggedPointer(const void *ptr); +_objc_isTaggedPointer(const void * _Nullable ptr); // Extract the tag value from the given tagged pointer object. // Assumes ptr is a valid tagged pointer object. // Does not check the validity of ptr's tag. static inline objc_tag_index_t -_objc_getTaggedPointerTag(const void *ptr); +_objc_getTaggedPointerTag(const void * _Nullable ptr); // Extract the payload from the given tagged pointer object. // Assumes ptr is a valid tagged pointer object. // The payload value is zero-extended. static inline uintptr_t -_objc_getTaggedPointerValue(const void *ptr); +_objc_getTaggedPointerValue(const void * _Nullable ptr); // Extract the payload from the given tagged pointer object. // Assumes ptr is a valid tagged pointer object. // The payload value is sign-extended. static inline intptr_t -_objc_getTaggedPointerSignedValue(const void *ptr); +_objc_getTaggedPointerSignedValue(const void * _Nullable ptr); // Don't use the values below. Use the declarations above. @@ -270,23 +306,23 @@ _objc_getTaggedPointerSignedValue(const void *ptr); #define _OBJC_TAG_EXT_SLOT_MASK 0xff #if OBJC_MSB_TAGGED_POINTERS -# define _OBJC_TAG_MASK (1ULL<<63) +# define _OBJC_TAG_MASK (1UL<<63) # define _OBJC_TAG_INDEX_SHIFT 60 # define _OBJC_TAG_SLOT_SHIFT 60 # define _OBJC_TAG_PAYLOAD_LSHIFT 4 # define _OBJC_TAG_PAYLOAD_RSHIFT 4 -# define _OBJC_TAG_EXT_MASK (0xfULL<<60) +# define _OBJC_TAG_EXT_MASK (0xfUL<<60) # define _OBJC_TAG_EXT_INDEX_SHIFT 52 # define _OBJC_TAG_EXT_SLOT_SHIFT 52 # define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 12 # define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12 #else -# define _OBJC_TAG_MASK 1 +# define _OBJC_TAG_MASK 1UL # define _OBJC_TAG_INDEX_SHIFT 1 # define _OBJC_TAG_SLOT_SHIFT 0 # define _OBJC_TAG_PAYLOAD_LSHIFT 0 # define _OBJC_TAG_PAYLOAD_RSHIFT 4 -# define _OBJC_TAG_EXT_MASK 0xfULL +# define _OBJC_TAG_EXT_MASK 0xfUL # define _OBJC_TAG_EXT_INDEX_SHIFT 4 # define _OBJC_TAG_EXT_SLOT_SHIFT 4 # define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 0 @@ -300,7 +336,7 @@ _objc_taggedPointersEnabled(void) return (objc_debug_taggedpointer_mask != 0); } -static inline void * +static inline void * _Nonnull _objc_makeTaggedPointer(objc_tag_index_t tag, uintptr_t value) { // PAYLOAD_LSHIFT and PAYLOAD_RSHIFT are the payload extraction shifts. @@ -309,7 +345,7 @@ _objc_makeTaggedPointer(objc_tag_index_t tag, uintptr_t value) // assert(_objc_taggedPointersEnabled()); if (tag <= OBJC_TAG_Last60BitPayload) { // assert(((value << _OBJC_TAG_PAYLOAD_RSHIFT) >> _OBJC_TAG_PAYLOAD_LSHIFT) == value); - return (void*) + return (void *) (_OBJC_TAG_MASK | ((uintptr_t)tag << _OBJC_TAG_INDEX_SHIFT) | ((value << _OBJC_TAG_PAYLOAD_RSHIFT) >> _OBJC_TAG_PAYLOAD_LSHIFT)); @@ -317,7 +353,7 @@ _objc_makeTaggedPointer(objc_tag_index_t tag, uintptr_t value) // assert(tag >= OBJC_TAG_First52BitPayload); // assert(tag <= OBJC_TAG_Last52BitPayload); // assert(((value << _OBJC_TAG_EXT_PAYLOAD_RSHIFT) >> _OBJC_TAG_EXT_PAYLOAD_LSHIFT) == value); - return (void*) + return (void *) (_OBJC_TAG_EXT_MASK | ((uintptr_t)(tag - OBJC_TAG_First52BitPayload) << _OBJC_TAG_EXT_INDEX_SHIFT) | ((value << _OBJC_TAG_EXT_PAYLOAD_RSHIFT) >> _OBJC_TAG_EXT_PAYLOAD_LSHIFT)); @@ -325,13 +361,13 @@ _objc_makeTaggedPointer(objc_tag_index_t tag, uintptr_t value) } static inline bool -_objc_isTaggedPointer(const void *ptr) +_objc_isTaggedPointer(const void * _Nullable ptr) { - return ((intptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK; + return ((uintptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK; } static inline objc_tag_index_t -_objc_getTaggedPointerTag(const void *ptr) +_objc_getTaggedPointerTag(const void * _Nullable ptr) { // assert(_objc_isTaggedPointer(ptr)); uintptr_t basicTag = ((uintptr_t)ptr >> _OBJC_TAG_INDEX_SHIFT) & _OBJC_TAG_INDEX_MASK; @@ -344,7 +380,7 @@ _objc_getTaggedPointerTag(const void *ptr) } static inline uintptr_t -_objc_getTaggedPointerValue(const void *ptr) +_objc_getTaggedPointerValue(const void * _Nullable ptr) { // assert(_objc_isTaggedPointer(ptr)); uintptr_t basicTag = ((uintptr_t)ptr >> _OBJC_TAG_INDEX_SHIFT) & _OBJC_TAG_INDEX_MASK; @@ -356,7 +392,7 @@ _objc_getTaggedPointerValue(const void *ptr) } static inline intptr_t -_objc_getTaggedPointerSignedValue(const void *ptr) +_objc_getTaggedPointerSignedValue(const void * _Nullable ptr) { // assert(_objc_isTaggedPointer(ptr)); uintptr_t basicTag = ((uintptr_t)ptr >> _OBJC_TAG_INDEX_SHIFT) & _OBJC_TAG_INDEX_MASK; @@ -384,22 +420,31 @@ _objc_getTaggedPointerSignedValue(const void *ptr) * * class_getMethodImplementation(object_getClass(obj), name); */ -OBJC_EXPORT IMP object_getMethodImplementation(id obj, SEL name) - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); +OBJC_EXPORT IMP _Nonnull +object_getMethodImplementation(id _Nullable obj, SEL _Nonnull name) + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); -OBJC_EXPORT IMP object_getMethodImplementation_stret(id obj, SEL name) - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0) +OBJC_EXPORT IMP _Nonnull +object_getMethodImplementation_stret(id _Nullable obj, SEL _Nonnull name) + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; // Instance-specific instance variable layout. -OBJC_EXPORT void _class_setIvarLayoutAccessor(Class cls_gen, const uint8_t* (*accessor) (id object)) +OBJC_EXPORT void +_class_setIvarLayoutAccessor(Class _Nullable cls, + const uint8_t* _Nullable (* _Nonnull accessor) + (id _Nullable object)) __OSX_AVAILABLE(10.7) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; -OBJC_EXPORT const uint8_t *_object_getIvarLayout(Class cls_gen, id object) + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; + +OBJC_EXPORT const uint8_t * _Nullable +_object_getIvarLayout(Class _Nullable cls, id _Nullable object) __OSX_AVAILABLE(10.7) - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE; /* "Unknown" includes non-object ivars and non-ARC non-__weak ivars @@ -414,230 +459,224 @@ typedef enum { objc_ivar_memoryUnretained // direct access / direct access } objc_ivar_memory_management_t; -OBJC_EXPORT objc_ivar_memory_management_t _class_getIvarMemoryManagement(Class cls, Ivar ivar) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); +OBJC_EXPORT objc_ivar_memory_management_t +_class_getIvarMemoryManagement(Class _Nullable cls, Ivar _Nonnull ivar) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); -OBJC_EXPORT BOOL _class_isFutureClass(Class cls) - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); +OBJC_EXPORT BOOL _class_isFutureClass(Class _Nullable cls) + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); // API to only be called by root classes like NSObject or NSProxy OBJC_EXPORT -id -_objc_rootRetain(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +id _Nonnull +_objc_rootRetain(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT void -_objc_rootRelease(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +_objc_rootRelease(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT bool -_objc_rootReleaseWasZero(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +_objc_rootReleaseWasZero(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT bool -_objc_rootTryRetain(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +_objc_rootTryRetain(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT bool -_objc_rootIsDeallocating(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +_objc_rootIsDeallocating(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT -id -_objc_rootAutorelease(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +id _Nonnull +_objc_rootAutorelease(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT uintptr_t -_objc_rootRetainCount(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +_objc_rootRetainCount(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT -id -_objc_rootInit(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +id _Nonnull +_objc_rootInit(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT -id -_objc_rootAllocWithZone(Class cls, malloc_zone_t *zone) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +id _Nullable +_objc_rootAllocWithZone(Class _Nonnull cls, malloc_zone_t * _Nullable zone) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT -id -_objc_rootAlloc(Class cls) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +id _Nullable +_objc_rootAlloc(Class _Nonnull cls) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT void -_objc_rootDealloc(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +_objc_rootDealloc(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT void -_objc_rootFinalize(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +_objc_rootFinalize(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT -malloc_zone_t * -_objc_rootZone(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +malloc_zone_t * _Nonnull +_objc_rootZone(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT uintptr_t -_objc_rootHash(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +_objc_rootHash(id _Nonnull obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT -void * +void * _Nonnull objc_autoreleasePoolPush(void) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); OBJC_EXPORT void -objc_autoreleasePoolPop(void *context) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +objc_autoreleasePoolPop(void * _Nonnull context) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT id objc_alloc(Class cls) - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_alloc(Class _Nullable cls) + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); -OBJC_EXPORT id objc_allocWithZone(Class cls) - OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_allocWithZone(Class _Nullable cls) + OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0); -OBJC_EXPORT id objc_retain(id obj) +OBJC_EXPORT id _Nullable +objc_retain(id _Nullable obj) __asm__("_objc_retain") - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT void objc_release(id obj) +OBJC_EXPORT void +objc_release(id _Nullable obj) __asm__("_objc_release") - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT id objc_autorelease(id obj) +OBJC_EXPORT id _Nullable +objc_autorelease(id _Nullable obj) __asm__("_objc_autorelease") - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); // Prepare a value at +1 for return through a +0 autoreleasing convention. -OBJC_EXPORT -id -objc_autoreleaseReturnValue(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_autoreleaseReturnValue(id _Nullable obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); // Prepare a value at +0 for return through a +0 autoreleasing convention. -OBJC_EXPORT -id -objc_retainAutoreleaseReturnValue(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_retainAutoreleaseReturnValue(id _Nullable obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); // Accept a value returned through a +0 autoreleasing convention for use at +1. -OBJC_EXPORT -id -objc_retainAutoreleasedReturnValue(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_retainAutoreleasedReturnValue(id _Nullable obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); // Accept a value returned through a +0 autoreleasing convention for use at +0. -OBJC_EXPORT -id -objc_unsafeClaimAutoreleasedReturnValue(id obj) - OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_unsafeClaimAutoreleasedReturnValue(id _Nullable obj) + OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0); -OBJC_EXPORT -void -objc_storeStrong(id *location, id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT void +objc_storeStrong(id _Nullable * _Nonnull location, id _Nullable obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT -id -objc_retainAutorelease(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_retainAutorelease(id _Nullable obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); // obsolete. -OBJC_EXPORT id objc_retain_autorelease(id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_retain_autorelease(id _Nullable obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT -id -objc_loadWeakRetained(id *location) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_loadWeakRetained(id _Nullable * _Nonnull location) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT -id -objc_initWeak(id *location, id val) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_initWeak(id _Nullable * _Nonnull location, id _Nullable val) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); // Like objc_storeWeak, but stores nil if the new object is deallocating // or the new object's class does not support weak references. // Returns the value stored (either the new object or nil). -OBJC_EXPORT -id -objc_storeWeakOrNil(id *location, id obj) - OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_storeWeakOrNil(id _Nullable * _Nonnull location, id _Nullable obj) + OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0); // Like objc_initWeak, but stores nil if the new object is deallocating // or the new object's class does not support weak references. // Returns the value stored (either the new object or nil). -OBJC_EXPORT -id -objc_initWeakOrNil(id *location, id val) - OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_initWeakOrNil(id _Nullable * _Nonnull location, id _Nullable val) + OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0); -OBJC_EXPORT -void -objc_destroyWeak(id *location) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT void +objc_destroyWeak(id _Nullable * _Nonnull location) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT -void -objc_copyWeak(id *to, id *from) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT void +objc_copyWeak(id _Nullable * _Nonnull to, id _Nullable * _Nonnull from) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT -void -objc_moveWeak(id *to, id *from) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT void +objc_moveWeak(id _Nullable * _Nonnull to, id _Nullable * _Nonnull from) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT -void +OBJC_EXPORT void _objc_autoreleasePoolPrint(void) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT BOOL objc_should_deallocate(id object) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT BOOL +objc_should_deallocate(id _Nonnull object) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT void objc_clear_deallocating(id object) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT void +objc_clear_deallocating(id _Nonnull object) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); // to make CF link for now -OBJC_EXPORT -void * +OBJC_EXPORT void * _Nonnull _objc_autoreleasePoolPush(void) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); -OBJC_EXPORT -void -_objc_autoreleasePoolPop(void *context) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT void +_objc_autoreleasePoolPop(void * _Nonnull context) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); // Extra @encode data for XPC, or NULL -OBJC_EXPORT const char *_protocol_getMethodTypeEncoding(Protocol *p, SEL sel, BOOL isRequiredMethod, BOOL isInstanceMethod) - OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nullable +_protocol_getMethodTypeEncoding(Protocol * _Nonnull proto, SEL _Nonnull sel, + BOOL isRequiredMethod, BOOL isInstanceMethod) + OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0); // API to only be called by classes that provide their own reference count storage -OBJC_EXPORT -void -_objc_deallocOnMainThreadHelper(void *context) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT void +_objc_deallocOnMainThreadHelper(void * _Nullable context) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); // On async versus sync deallocation and the _dealloc2main flag // diff --git a/runtime/objc-load.h b/runtime/objc-load.h index 8ec1fa2..0e334a2 100644 --- a/runtime/objc-load.h +++ b/runtime/objc-load.h @@ -35,20 +35,21 @@ /* dynamically loading Mach-O object files that contain Objective-C code */ OBJC_EXPORT long objc_loadModules ( - char *modlist[], - void *errStream, - void (*class_callback) (Class, Category), - /*headerType*/ struct mach_header **hdr_addr, - char *debug_file + char * _Nullable modlist[_Nullable], + void * _Nullable errStream, + void (* _Nullable class_callback) (Class _Nullable, Category _Nullable), + /*headerType*/ struct mach_header * _Nullable * _Nullable hdr_addr, + char * _Nullable debug_file ) OBJC2_UNAVAILABLE; + OBJC_EXPORT int objc_loadModule ( - char * moduleName, - void (*class_callback) (Class, Category), - int * errorCode + char * _Nullable moduleName, + void (* _Nullable class_callback) (Class _Nullable, Category _Nullable), + int * _Nullable errorCode ) OBJC2_UNAVAILABLE; OBJC_EXPORT long objc_unloadModules( - void *errorStream, /* input (optional) */ - void (*unloadCallback)(Class, Category) /* input (optional) */ + void * _Nullable errorStream, /* input (optional) */ + void (* _Nullable unloadCallback)(Class _Nullable, Category _Nullable) /* input (optional) */ ) OBJC2_UNAVAILABLE; #endif /* _OBJC_LOAD_H_ */ diff --git a/runtime/objc-lockdebug.h b/runtime/objc-lockdebug.h index 211b7eb..0fdee6f 100644 --- a/runtime/objc-lockdebug.h +++ b/runtime/objc-lockdebug.h @@ -21,7 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ -#if DEBUG +#if LOCKDEBUG extern void lockdebug_assert_all_locks_locked(); extern void lockdebug_assert_no_locks_locked(); extern void lockdebug_setInForkPrepare(bool); diff --git a/runtime/objc-lockdebug.mm b/runtime/objc-lockdebug.mm index 7b38de6..c1ac7a4 100644 --- a/runtime/objc-lockdebug.mm +++ b/runtime/objc-lockdebug.mm @@ -28,7 +28,7 @@ #include "objc-private.h" -#if DEBUG && !TARGET_OS_WIN32 +#if LOCKDEBUG && !TARGET_OS_WIN32 #include @@ -65,23 +65,41 @@ inForkPrepare() struct lockorder { const void *l; std::vector predecessors; + + mutable std::unordered_map memo; + + lockorder(const void *newl) : l(newl) { } }; -static std::unordered_map lockOrderList; +static std::unordered_map lockOrderList; +// not mutex_t because we don't want lock debugging on this lock +static mutex_tt lockOrderLock; static bool -lockPrecedesLock(const lockorder& oldlock, const lockorder& newlock) +lockPrecedesLock(const lockorder *oldlock, const lockorder *newlock) { - for (const auto *pre : newlock.predecessors) { - if (&oldlock == pre) return true; - if (lockPrecedesLock(oldlock, *pre)) return true; + auto memoed = newlock->memo.find(oldlock); + if (memoed != newlock->memo.end()) { + return memoed->second; } - return false; + + bool result = false; + for (const auto *pre : newlock->predecessors) { + if (oldlock == pre || lockPrecedesLock(oldlock, pre)) { + result = true; + break; + } + } + + newlock->memo[oldlock] = result; + return result; } static bool lockPrecedesLock(const void *oldlock, const void *newlock) { + mutex_tt::locker lock(lockOrderLock); + auto oldorder = lockOrderList.find(oldlock); auto neworder = lockOrderList.find(newlock); if (neworder == lockOrderList.end() || oldorder == lockOrderList.end()) { @@ -93,6 +111,8 @@ lockPrecedesLock(const void *oldlock, const void *newlock) static bool lockUnorderedWithLock(const void *oldlock, const void *newlock) { + mutex_tt::locker lock(lockOrderLock); + auto oldorder = lockOrderList.find(oldlock); auto neworder = lockOrderList.find(newlock); if (neworder == lockOrderList.end() || oldorder == lockOrderList.end()) { @@ -114,18 +134,20 @@ void lockdebug_lock_precedes_lock(const void *oldlock, const void *newlock) _objc_fatal("contradiction in lock order declaration"); } + mutex_tt::locker lock(lockOrderLock); + auto oldorder = lockOrderList.find(oldlock); auto neworder = lockOrderList.find(newlock); if (oldorder == lockOrderList.end()) { - lockOrderList[oldlock] = lockorder{oldlock, {}}; + lockOrderList[oldlock] = new lockorder(oldlock); oldorder = lockOrderList.find(oldlock); } if (neworder == lockOrderList.end()) { - lockOrderList[newlock] = lockorder{newlock, {}}; + lockOrderList[newlock] = new lockorder(newlock); neworder = lockOrderList.find(newlock); } - neworder->second.predecessors.push_back(&oldorder->second); + neworder->second->predecessors.push_back(oldorder->second); } @@ -220,6 +242,11 @@ setLock(objc_lock_list& locks, const void *lock, lockkind kind) // Locks not in AllLocks are exempt (i.e. @synchronize locks) if (&locks != &AllLocks() && AllLocks().find(lock) != AllLocks().end()) { for (auto& oldlock : locks) { + if (AllLocks().find(oldlock.first) == AllLocks().end()) { + // oldlock is exempt + continue; + } + if (lockPrecedesLock(lock, oldlock.first)) { _objc_fatal("lock %p (%s) incorrectly acquired before %p (%s)", oldlock.first, sym(oldlock.first), lock, sym(lock)); diff --git a/runtime/objc-locks.h b/runtime/objc-locks.h index 05bd22f..00654eb 100644 --- a/runtime/objc-locks.h +++ b/runtime/objc-locks.h @@ -54,6 +54,8 @@ extern void SideTableForceResetAll(); extern void SideTableDefineLockOrder(); extern void SideTableLocksPrecedeLock(const void *newlock); extern void SideTableLocksSucceedLock(const void *oldlock); +extern void SideTableLocksPrecedeLocks(StripedMap& newlocks); +extern void SideTableLocksSucceedLocks(StripedMap& oldlocks); #if __OBJC2__ #include "objc-locks-new.h" diff --git a/runtime/objc-os.h b/runtime/objc-os.h index 7785d4a..0104d7d 100644 --- a/runtime/objc-os.h +++ b/runtime/objc-os.h @@ -690,50 +690,6 @@ static bool is_valid_direct_key(tls_key_t k) { } #endif -#if __arm__ - -// rdar://9162780 _pthread_get/setspecific_direct are inefficient -// copied from libdispatch - -__attribute__((const)) -static ALWAYS_INLINE void** -tls_base(void) -{ - uintptr_t p; -#if defined(__arm__) && defined(_ARM_ARCH_6) - __asm__("mrc p15, 0, %[p], c13, c0, 3" : [p] "=&r" (p)); - return (void**)(p & ~0x3ul); -#else -#error tls_base not implemented -#endif -} - - -static ALWAYS_INLINE void -tls_set_direct(void **tsdb, tls_key_t k, void *v) -{ - assert(is_valid_direct_key(k)); - - tsdb[k] = v; -} -#define tls_set_direct(k, v) \ - tls_set_direct(tls_base(), (k), (v)) - - -static ALWAYS_INLINE void * -tls_get_direct(void **tsdb, tls_key_t k) -{ - assert(is_valid_direct_key(k)); - - return tsdb[k]; -} -#define tls_get_direct(k) \ - tls_get_direct(tls_base(), (k)) - -// arm -#else -// not arm - static inline void *tls_get_direct(tls_key_t k) { assert(is_valid_direct_key(k)); @@ -755,9 +711,6 @@ static inline void tls_set_direct(tls_key_t k, void *value) } } -// not arm -#endif - // SUPPORT_DIRECT_THREAD_KEYS #endif @@ -789,11 +742,17 @@ template class monitor_tt; template class rwlock_tt; template class recursive_mutex_tt; -using spinlock_t = mutex_tt; -using mutex_t = mutex_tt; -using monitor_t = monitor_tt; -using rwlock_t = rwlock_tt; -using recursive_mutex_t = recursive_mutex_tt; +#if DEBUG +# define LOCKDEBUG 1 +#else +# define LOCKDEBUG 0 +#endif + +using spinlock_t = mutex_tt; +using mutex_t = mutex_tt; +using monitor_t = monitor_tt; +using rwlock_t = rwlock_tt; +using recursive_mutex_t = recursive_mutex_tt; // Use fork_unsafe_lock to get a lock that isn't // acquired and released around fork(). @@ -858,8 +817,19 @@ class mutex_tt : nocopy_t { lock1->unlock(); if (lock2 != lock1) lock2->unlock(); } + + // Scoped lock and unlock + class locker : nocopy_t { + mutex_tt& lock; + public: + locker(mutex_tt& newLock) + : lock(newLock) { lock.lock(); } + ~locker() { lock.unlock(); } + }; }; +using mutex_locker_t = mutex_tt::locker; + template class recursive_mutex_tt : nocopy_t { @@ -1237,27 +1207,35 @@ ustrdupMaybeNil(const uint8_t *str) // OS version checking: // // sdkVersion() -// DYLD_OS_VERSION(mac, ios, tv, watch) -// sdkIsOlderThan(mac, ios, tv, watch) -// sdkIsAtLeast(mac, ios, tv, watch) +// DYLD_OS_VERSION(mac, ios, tv, watch, bridge) +// sdkIsOlderThan(mac, ios, tv, watch, bridge) +// sdkIsAtLeast(mac, ios, tv, watch, bridge) // // This version order matches OBJC_AVAILABLE. #if TARGET_OS_OSX -# define DYLD_OS_VERSION(x, i, t, w) DYLD_MACOSX_VERSION_##x +# define DYLD_OS_VERSION(x, i, t, w, b) DYLD_MACOSX_VERSION_##x # define sdkVersion() dyld_get_program_sdk_version() #elif TARGET_OS_IOS -# define DYLD_OS_VERSION(x, i, t, w) DYLD_IOS_VERSION_##i +# define DYLD_OS_VERSION(x, i, t, w, b) DYLD_IOS_VERSION_##i # define sdkVersion() dyld_get_program_sdk_version() #elif TARGET_OS_TV // dyld does not currently have distinct constants for tvOS -# define DYLD_OS_VERSION(x, i, t, w) DYLD_IOS_VERSION_##t +# define DYLD_OS_VERSION(x, i, t, w, b) DYLD_IOS_VERSION_##t # define sdkVersion() dyld_get_program_sdk_version() +#elif TARGET_OS_BRIDGE +# if TARGET_OS_WATCH +# error bridgeOS 1.0 not supported +# endif + // fixme don't need bridgeOS versioning yet +# define DYLD_OS_VERSION(x, i, t, w, b) DYLD_IOS_VERSION_##t +# define sdkVersion() dyld_get_program_sdk_bridge_os_version() + #elif TARGET_OS_WATCH -# define DYLD_OS_VERSION(x, i, t, w) DYLD_WATCHOS_VERSION_##w +# define DYLD_OS_VERSION(x, i, t, w, b) DYLD_WATCHOS_VERSION_##w // watchOS has its own API for compatibility reasons # define sdkVersion() dyld_get_program_sdk_watch_os_version() @@ -1266,16 +1244,17 @@ ustrdupMaybeNil(const uint8_t *str) #endif -#define sdkIsOlderThan(x, i, t, w) \ - (sdkVersion() < DYLD_OS_VERSION(x, i, t, w)) -#define sdkIsAtLeast(x, i, t, w) \ - (sdkVersion() >= DYLD_OS_VERSION(x, i, t, w)) +#define sdkIsOlderThan(x, i, t, w, b) \ + (sdkVersion() < DYLD_OS_VERSION(x, i, t, w, b)) +#define sdkIsAtLeast(x, i, t, w, b) \ + (sdkVersion() >= DYLD_OS_VERSION(x, i, t, w, b)) // Allow bare 0 to be used in DYLD_OS_VERSION() and sdkIsOlderThan() #define DYLD_MACOSX_VERSION_0 0 #define DYLD_IOS_VERSION_0 0 #define DYLD_TVOS_VERSION_0 0 #define DYLD_WATCHOS_VERSION_0 0 +#define DYLD_BRIDGEOS_VERSION_0 0 // Pretty-print a DYLD_*_VERSION_* constant. #define SDK_FORMAT "%hu.%hhu.%hhu" diff --git a/runtime/objc-os.mm b/runtime/objc-os.mm index 3049901..b2fc8ac 100644 --- a/runtime/objc-os.mm +++ b/runtime/objc-os.mm @@ -538,6 +538,39 @@ map_images_nolock(unsigned mhCount, const char * const mhPaths[], } } #endif + +#if TARGET_OS_OSX + // Disable +initialize fork safety if the app is too old (< 10.13). + // Disable +initialize fork safety if the app has a + // __DATA,__objc_fork_ok section. + + if (dyld_get_program_sdk_version() < DYLD_MACOSX_VERSION_10_13) { + DisableInitializeForkSafety = true; + if (PrintInitializing) { + _objc_inform("INITIALIZE: disabling +initialize fork " + "safety enforcement because the app is " + "too old (SDK version " SDK_FORMAT ")", + FORMAT_SDK(dyld_get_program_sdk_version())); + } + } + + for (uint32_t i = 0; i < hCount; i++) { + auto hi = hList[i]; + auto mh = hi->mhdr(); + if (mh->filetype != MH_EXECUTE) continue; + unsigned long size; + if (getsectiondata(hi->mhdr(), "__DATA", "__objc_fork_ok", &size)) { + DisableInitializeForkSafety = true; + if (PrintInitializing) { + _objc_inform("INITIALIZE: disabling +initialize fork " + "safety enforcement because the app has " + "a __DATA,__objc_fork_ok section"); + } + } + break; // assume only one MH_EXECUTE image + } +#endif + } if (hCount > 0) { @@ -618,7 +651,7 @@ static void static_init() **********************************************************************/ // Declare lock ordering. -#if DEBUG +#if LOCKDEBUG __attribute__((constructor)) static void defineLockOrder() { @@ -667,37 +700,36 @@ static void defineLockOrder() StructLocks.succeedLock(&loadMethodLock); CppObjectLocks.succeedLock(&loadMethodLock); - // PropertyLocks and CppObjectLocks precede everything - // because they are held while objc_retain() or C++ copy are called. + // PropertyLocks and CppObjectLocks and AssociationManagerLock + // precede everything because they are held while objc_retain() + // or C++ copy are called. // (StructLocks do not precede everything because it calls memmove only.) - PropertyLocks.precedeLock(&classInitLock); - CppObjectLocks.precedeLock(&classInitLock); + auto PropertyAndCppObjectAndAssocLocksPrecedeLock = [&](const void *lock) { + PropertyLocks.precedeLock(lock); + CppObjectLocks.precedeLock(lock); + lockdebug_lock_precedes_lock(&AssociationsManagerLock, lock); + }; #if __OBJC2__ - PropertyLocks.precedeLock(&runtimeLock); - CppObjectLocks.precedeLock(&runtimeLock); - PropertyLocks.precedeLock(&DemangleCacheLock); - CppObjectLocks.precedeLock(&DemangleCacheLock); + PropertyAndCppObjectAndAssocLocksPrecedeLock(&runtimeLock); + PropertyAndCppObjectAndAssocLocksPrecedeLock(&DemangleCacheLock); #else - PropertyLocks.precedeLock(&methodListLock); - CppObjectLocks.precedeLock(&methodListLock); - PropertyLocks.precedeLock(&classLock); - CppObjectLocks.precedeLock(&classLock); - PropertyLocks.precedeLock(&NXUniqueStringLock); - CppObjectLocks.precedeLock(&NXUniqueStringLock); - PropertyLocks.precedeLock(&impLock); - CppObjectLocks.precedeLock(&impLock); + PropertyAndCppObjectAndAssocLocksPrecedeLock(&methodListLock); + PropertyAndCppObjectAndAssocLocksPrecedeLock(&classLock); + PropertyAndCppObjectAndAssocLocksPrecedeLock(&NXUniqueStringLock); + PropertyAndCppObjectAndAssocLocksPrecedeLock(&impLock); #endif - PropertyLocks.precedeLock(&selLock); - CppObjectLocks.precedeLock(&selLock); - PropertyLocks.precedeLock(&cacheUpdateLock); - CppObjectLocks.precedeLock(&cacheUpdateLock); - PropertyLocks.precedeLock(&objcMsgLogLock); - CppObjectLocks.precedeLock(&objcMsgLogLock); - PropertyLocks.precedeLock(&AltHandlerDebugLock); - CppObjectLocks.precedeLock(&AltHandlerDebugLock); + PropertyAndCppObjectAndAssocLocksPrecedeLock(&classInitLock); + PropertyAndCppObjectAndAssocLocksPrecedeLock(&selLock); + PropertyAndCppObjectAndAssocLocksPrecedeLock(&cacheUpdateLock); + PropertyAndCppObjectAndAssocLocksPrecedeLock(&objcMsgLogLock); + PropertyAndCppObjectAndAssocLocksPrecedeLock(&AltHandlerDebugLock); + + SideTableLocksSucceedLocks(PropertyLocks); + SideTableLocksSucceedLocks(CppObjectLocks); + SideTableLocksSucceedLock(&AssociationsManagerLock); + PropertyLocks.precedeLock(&AssociationsManagerLock); CppObjectLocks.precedeLock(&AssociationsManagerLock); - // fixme side table #if __OBJC2__ lockdebug_lock_precedes_lock(&classInitLock, &runtimeLock); @@ -707,6 +739,7 @@ static void defineLockOrder() // Runtime operations may occur inside SideTable locks // (such as storeWeak calling getMethodImplementation) SideTableLocksPrecedeLock(&runtimeLock); + SideTableLocksPrecedeLock(&classInitLock); // Some operations may occur inside runtimeLock. lockdebug_lock_precedes_lock(&runtimeLock, &selLock); lockdebug_lock_precedes_lock(&runtimeLock, &cacheUpdateLock); @@ -715,6 +748,7 @@ static void defineLockOrder() // Runtime operations may occur inside SideTable locks // (such as storeWeak calling getMethodImplementation) SideTableLocksPrecedeLock(&methodListLock); + SideTableLocksPrecedeLock(&classInitLock); // Method lookup and fixup. lockdebug_lock_precedes_lock(&methodListLock, &classLock); lockdebug_lock_precedes_lock(&methodListLock, &selLock); @@ -730,11 +764,15 @@ static void defineLockOrder() StructLocks.defineLockOrder(); CppObjectLocks.defineLockOrder(); } -// DEBUG +// LOCKDEBUG #endif +static bool ForkIsMultithreaded; void _objc_atfork_prepare() { + // Save threaded-ness for the child's use. + ForkIsMultithreaded = pthread_is_threaded_np(); + lockdebug_assert_no_locks_locked(); lockdebug_setInForkPrepare(true); @@ -795,6 +833,11 @@ void _objc_atfork_parent() void _objc_atfork_child() { + // Turn on +initialize fork safety enforcement if applicable. + if (ForkIsMultithreaded && !DisableInitializeForkSafety) { + MultithreadedForkChild = true; + } + lockdebug_assert_all_locks_locked(); CppObjectLocks.forceResetAll(); diff --git a/runtime/objc-private.h b/runtime/objc-private.h index b34b591..aac2d51 100644 --- a/runtime/objc-private.h +++ b/runtime/objc-private.h @@ -603,14 +603,6 @@ class monitor_locker_t : nocopy_t { ~monitor_locker_t() { lock.leave(); } }; -class mutex_locker_t : nocopy_t { - mutex_t& lock; - public: - mutex_locker_t(mutex_t& newLock) - : lock(newLock) { lock.lock(); } - ~mutex_locker_t() { lock.unlock(); } -}; - class recursive_mutex_locker_t : nocopy_t { recursive_mutex_t& lock; public: @@ -715,6 +707,8 @@ extern void layout_bitmap_print(layout_bitmap bits); // fixme runtime +extern bool MultithreadedForkChild; +extern id objc_noop_imp(id self, SEL _cmd); extern Class look_up_class(const char *aClassName, bool includeUnconnected, bool includeClassHandler); extern "C" void map_images(unsigned count, const char * const paths[], const struct mach_header * const mhdrs[]); @@ -920,6 +914,11 @@ class StripedMap { // assumes defineLockOrder is also called lockdebug_lock_precedes_lock(oldlock, &array[0].value); } + + const void *getLock(int i) { + if (i < StripeCount) return &array[i].value; + else return nil; + } #if DEBUG StripedMap() { diff --git a/runtime/objc-references.mm b/runtime/objc-references.mm index 20bf807..c1119f0 100644 --- a/runtime/objc-references.mm +++ b/runtime/objc-references.mm @@ -234,12 +234,14 @@ id _object_get_associative_reference(id object, void *key) { ObjcAssociation &entry = j->second; value = entry.value(); policy = entry.policy(); - if (policy & OBJC_ASSOCIATION_GETTER_RETAIN) ((id(*)(id, SEL))objc_msgSend)(value, SEL_retain); + if (policy & OBJC_ASSOCIATION_GETTER_RETAIN) { + objc_retain(value); + } } } } if (value && (policy & OBJC_ASSOCIATION_GETTER_AUTORELEASE)) { - ((id(*)(id, SEL))objc_msgSend)(value, SEL_autorelease); + objc_autorelease(value); } return value; } @@ -247,7 +249,7 @@ id _object_get_associative_reference(id object, void *key) { static id acquireValue(id value, uintptr_t policy) { switch (policy & 0xFF) { case OBJC_ASSOCIATION_SETTER_RETAIN: - return ((id(*)(id, SEL))objc_msgSend)(value, SEL_retain); + return objc_retain(value); case OBJC_ASSOCIATION_SETTER_COPY: return ((id(*)(id, SEL))objc_msgSend)(value, SEL_copy); } @@ -256,7 +258,7 @@ static id acquireValue(id value, uintptr_t policy) { static void releaseValue(id value, uintptr_t policy) { if (policy & OBJC_ASSOCIATION_SETTER_RETAIN) { - ((id(*)(id, SEL))objc_msgSend)(value, SEL_release); + return objc_release(value); } } diff --git a/runtime/objc-runtime-new.mm b/runtime/objc-runtime-new.mm index 37b2f6f..8ad820c 100644 --- a/runtime/objc-runtime-new.mm +++ b/runtime/objc-runtime-new.mm @@ -60,10 +60,6 @@ static void fixupMessageRef(message_ref_t *msg); static bool MetaclassNSObjectAWZSwizzled; static bool ClassNSObjectRRSwizzled; -id objc_noop_imp(id self, SEL _cmd __unused) { - return self; -} - /*********************************************************************** * Lock management @@ -96,6 +92,13 @@ void lock_init(void) } +/*********************************************************************** +* Class structure decoding +**********************************************************************/ + +const uintptr_t objc_debug_class_rw_data_mask = FAST_DATA_MASK; + + /*********************************************************************** * Non-pointer isa decoding **********************************************************************/ @@ -4654,7 +4657,7 @@ IMP lookUpImpOrForward(Class cls, SEL sel, id inst, // Try superclass caches and method lists. { unsigned attempts = unreasonableClassCount(); - for (Class curClass = cls; + for (Class curClass = cls->superclass; curClass != nil; curClass = curClass->superclass) { diff --git a/runtime/objc-runtime-old.h b/runtime/objc-runtime-old.h index 5f0ff02..d8f966b 100644 --- a/runtime/objc-runtime-old.h +++ b/runtime/objc-runtime-old.h @@ -300,6 +300,14 @@ struct objc_class : objc_object { const char *mangledName() { return name; } const char *demangledName() { return name; } const char *nameForLogging() { return name; } + + bool isRootClass() { + return superclass == nil; + } + + bool isRootMetaclass() { + return ISA() == (Class)this; + } bool isMetaClass() { return info & CLS_META; diff --git a/runtime/objc-runtime.mm b/runtime/objc-runtime.mm index e9efe55..ba1b38d 100644 --- a/runtime/objc-runtime.mm +++ b/runtime/objc-runtime.mm @@ -94,6 +94,19 @@ header_info *LastHeader = 0; // NULL means invalid; recompute it int HeaderCount = 0; +// Set to true on the child side of fork() +// if the parent process was multithreaded when fork() was called. +bool MultithreadedForkChild = false; + + +/*********************************************************************** +* objc_noop_imp. Used when we need to install a do-nothing method somewhere. +**********************************************************************/ +id objc_noop_imp(id self, SEL _cmd __unused) { + return self; +} + + /*********************************************************************** * objc_getClass. Return the id of the named class. If the class does * not exist, call _objc_classLoader and then objc_classHandler, either of diff --git a/runtime/objc-sel-table.s b/runtime/objc-sel-table.s index 359df9b..c4dd405 100644 --- a/runtime/objc-sel-table.s +++ b/runtime/objc-sel-table.s @@ -21,24 +21,31 @@ __objc_opt_data: .space PAGE_MAX_SIZE-28 /* space for selopt, smax/capacity=524288, blen/mask=262143+1 */ -.space 262144 /* mask tab */ -.space 524288 /* checkbytes */ -.space 524288*4 /* offsets */ +.space 4*(8+256) /* header and scramble */ +.space 262144 /* mask tab */ +.space 524288 /* checkbytes */ +.space 524288*4 /* offsets */ /* space for clsopt, smax/capacity=65536, blen/mask=16383+1 */ +.space 4*(8+256) /* header and scramble */ .space 16384 /* mask tab */ .space 65536 /* checkbytes */ .space 65536*12 /* offsets to name and class and header_info */ -.space PAGE_MAX_SIZE /* some duplicate classes */ +.space 512*8 /* some duplicate classes */ -/* space for protocolopt, smax/capacity=8192, blen/mask=4095+1 */ -.space 4096 /* mask tab */ -.space 8192 /* checkbytes */ -.space 8192*4 /* offsets */ +/* space for some demangled protocol names */ +.space 1024 + +/* space for protocolopt, smax/capacity=16384, blen/mask=8191+1 */ +.space 4*(8+256) /* header and scramble */ +.space 8192 /* mask tab */ +.space 16384 /* checkbytes */ +.space 16384*8 /* offsets */ /* space for header_info (RO) structures */ .space 16384 + .section __DATA,__objc_opt_rw .align 3 .private_extern __objc_opt_rw_data @@ -46,11 +53,11 @@ __objc_opt_rw_data: /* space for header_info (RW) structures */ .space 16384 -/* space for 8192 protocols */ +/* space for 16384 protocols */ #if __LP64__ -.space 8192 * 11 * 8 +.space 16384 * 12 * 8 #else -.space 8192 * 11 * 4 +.space 16384 * 12 * 4 #endif diff --git a/runtime/objc-sync.h b/runtime/objc-sync.h index 93a96fc..e9ab64f 100644 --- a/runtime/objc-sync.h +++ b/runtime/objc-sync.h @@ -35,33 +35,25 @@ * * @return OBJC_SYNC_SUCCESS once lock is acquired. */ -OBJC_EXPORT int objc_sync_enter(id obj) - OBJC_AVAILABLE(10.3, 2.0, 9.0, 1.0); +OBJC_EXPORT int +objc_sync_enter(id _Nonnull obj) + OBJC_AVAILABLE(10.3, 2.0, 9.0, 1.0, 2.0); /** * End synchronizing on 'obj'. * - * @param obj The objet to end synchronizing on. + * @param obj The object to end synchronizing on. * * @return OBJC_SYNC_SUCCESS or OBJC_SYNC_NOT_OWNING_THREAD_ERROR */ -OBJC_EXPORT int objc_sync_exit(id obj) - OBJC_AVAILABLE(10.3, 2.0, 9.0, 1.0); - -// The wait/notify functions have never worked correctly and no longer exist. -OBJC_EXPORT int objc_sync_wait(id obj, long long milliSecondsMaxWait) - UNAVAILABLE_ATTRIBUTE; -OBJC_EXPORT int objc_sync_notify(id obj) - UNAVAILABLE_ATTRIBUTE; -OBJC_EXPORT int objc_sync_notifyAll(id obj) - UNAVAILABLE_ATTRIBUTE; +OBJC_EXPORT int +objc_sync_exit(id _Nonnull obj) + OBJC_AVAILABLE(10.3, 2.0, 9.0, 1.0, 2.0); enum { - OBJC_SYNC_SUCCESS = 0, - OBJC_SYNC_NOT_OWNING_THREAD_ERROR = -1, - OBJC_SYNC_TIMED_OUT = -2, - OBJC_SYNC_NOT_INITIALIZED = -3 + OBJC_SYNC_SUCCESS = 0, + OBJC_SYNC_NOT_OWNING_THREAD_ERROR = -1 }; -#endif // __OBJC_SNYC_H_ +#endif // __OBJC_SYNC_H_ diff --git a/runtime/objc.h b/runtime/objc.h index 6cf776b..5064016 100644 --- a/runtime/objc.h +++ b/runtime/objc.h @@ -39,7 +39,7 @@ typedef struct objc_class *Class; /// Represents an instance of a class. struct objc_object { - Class isa OBJC_ISA_AVAILABILITY; + Class _Nonnull isa OBJC_ISA_AVAILABILITY; }; /// A pointer to an instance of a class. @@ -53,7 +53,7 @@ typedef struct objc_selector *SEL; #if !OBJC_OLD_DISPATCH_PROTOTYPES typedef void (*IMP)(void /* id, SEL, ... */ ); #else -typedef id (*IMP)(id, SEL, ...); +typedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull, ...); #endif /// Type to represent a boolean value. @@ -135,8 +135,8 @@ typedef id (*IMP)(id, SEL, ...); * * @return A C string indicating the name of the selector. */ -OBJC_EXPORT const char *sel_getName(SEL sel) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nonnull sel_getName(SEL _Nonnull sel) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Registers a method with the Objective-C runtime system, maps the method @@ -150,8 +150,8 @@ OBJC_EXPORT const char *sel_getName(SEL sel) * method’s selector before you can add the method to a class definition. If the method name * has already been registered, this function simply returns the selector. */ -OBJC_EXPORT SEL sel_registerName(const char *str) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT SEL _Nonnull sel_registerName(const char * _Nonnull str) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Returns the class name of a given object. @@ -160,8 +160,8 @@ OBJC_EXPORT SEL sel_registerName(const char *str) * * @return The name of the class of which \e obj is an instance. */ -OBJC_EXPORT const char *object_getClassName(id obj) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nonnull object_getClassName(id _Nullable obj) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Returns a pointer to any extra bytes allocated with an instance given object. @@ -179,8 +179,8 @@ OBJC_EXPORT const char *object_getClassName(id obj) * guaranteed, even if the area following the object's last ivar is more aligned than that. * @note In a garbage-collected environment, the memory is scanned conservatively. */ -OBJC_EXPORT void *object_getIndexedIvars(id obj) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) +OBJC_EXPORT void * _Nullable object_getIndexedIvars(id _Nullable obj) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) OBJC_ARC_UNAVAILABLE; /** @@ -193,8 +193,8 @@ OBJC_EXPORT void *object_getIndexedIvars(id obj) * @warning On some platforms, an invalid reference (to invalid memory addresses) can cause * a crash. */ -OBJC_EXPORT BOOL sel_isMapped(SEL sel) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT BOOL sel_isMapped(SEL _Nonnull sel) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Registers a method name with the Objective-C runtime system. @@ -208,19 +208,19 @@ OBJC_EXPORT BOOL sel_isMapped(SEL sel) * and returned \c NULL if the selector was not found. This was changed for safety, because it was * observed that many of the callers of this function did not check the return value for \c NULL. */ -OBJC_EXPORT SEL sel_getUid(const char *str) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT SEL _Nonnull sel_getUid(const char * _Nonnull str) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); typedef const void* objc_objectptr_t; // Obsolete ARC conversions. -OBJC_EXPORT id objc_retainedObject(objc_objectptr_t obj) +OBJC_EXPORT id _Nullable objc_retainedObject(objc_objectptr_t _Nullable obj) OBJC_UNAVAILABLE("use CFBridgingRelease() or a (__bridge_transfer id) cast instead"); -OBJC_EXPORT id objc_unretainedObject(objc_objectptr_t obj) +OBJC_EXPORT id _Nullable objc_unretainedObject(objc_objectptr_t _Nullable obj) OBJC_UNAVAILABLE("use a (__bridge id) cast instead"); -OBJC_EXPORT objc_objectptr_t objc_unretainedPointer(id obj) +OBJC_EXPORT objc_objectptr_t _Nullable objc_unretainedPointer(id _Nullable obj) OBJC_UNAVAILABLE("use a __bridge cast instead"); diff --git a/runtime/runtime.h b/runtime/runtime.h index 8ed2f43..ad68c90 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -53,18 +53,18 @@ typedef struct objc_category *Category; typedef struct objc_property *objc_property_t; struct objc_class { - Class isa OBJC_ISA_AVAILABILITY; + Class _Nonnull isa OBJC_ISA_AVAILABILITY; #if !__OBJC2__ - Class super_class OBJC2_UNAVAILABLE; - const char *name OBJC2_UNAVAILABLE; + Class _Nullable super_class OBJC2_UNAVAILABLE; + const char * _Nonnull name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; - struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; - struct objc_method_list **methodLists OBJC2_UNAVAILABLE; - struct objc_cache *cache OBJC2_UNAVAILABLE; - struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; + struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE; + struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE; + struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE; + struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE; #endif } OBJC2_UNAVAILABLE; @@ -80,14 +80,14 @@ typedef struct objc_object Protocol; /// Defines a method struct objc_method_description { - SEL name; /**< The name of the method */ - char *types; /**< The types of the method arguments */ + SEL _Nullable name; /**< The name of the method */ + char * _Nullable types; /**< The types of the method arguments */ }; /// Defines a property attribute typedef struct { - const char *name; /**< The name of the attribute */ - const char *value; /**< The value of the attribute (usually empty) */ + const char * _Nonnull name; /**< The name of the attribute */ + const char * _Nonnull value; /**< The value of the attribute (usually empty) */ } objc_property_attribute_t; @@ -103,8 +103,8 @@ typedef struct { * * @return A copy of \e obj. */ -OBJC_EXPORT id object_copy(id obj, size_t size) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) +OBJC_EXPORT id _Nullable object_copy(id _Nullable obj, size_t size) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) OBJC_ARC_UNAVAILABLE; /** @@ -114,8 +114,9 @@ OBJC_EXPORT id object_copy(id obj, size_t size) * * @return nil */ -OBJC_EXPORT id object_dispose(id obj) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) +OBJC_EXPORT id _Nullable +object_dispose(id _Nullable obj) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) OBJC_ARC_UNAVAILABLE; /** @@ -126,8 +127,9 @@ OBJC_EXPORT id object_dispose(id obj) * @return The class object of which \e object is an instance, * or \c Nil if \e object is \c nil. */ -OBJC_EXPORT Class object_getClass(id obj) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Class _Nullable +object_getClass(id _Nullable obj) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Sets the class of an object. @@ -137,8 +139,9 @@ OBJC_EXPORT Class object_getClass(id obj) * * @return The previous value of \e object's class, or \c Nil if \e object is \c nil. */ -OBJC_EXPORT Class object_setClass(id obj, Class cls) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Class _Nullable +object_setClass(id _Nullable obj, Class _Nonnull cls) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** @@ -148,8 +151,9 @@ OBJC_EXPORT Class object_setClass(id obj, Class cls) * * @return true if the object is a class or metaclass, false otherwise. */ -OBJC_EXPORT BOOL object_isClass(id obj) - OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0); +OBJC_EXPORT BOOL +object_isClass(id _Nullable obj) + OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0, 2.0); /** @@ -163,8 +167,9 @@ OBJC_EXPORT BOOL object_isClass(id obj) * @note \c object_getIvar is faster than \c object_getInstanceVariable if the Ivar * for the instance variable is already known. */ -OBJC_EXPORT id object_getIvar(id obj, Ivar ivar) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +object_getIvar(id _Nullable obj, Ivar _Nonnull ivar) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Sets the value of an instance variable in an object. @@ -179,8 +184,9 @@ OBJC_EXPORT id object_getIvar(id obj, Ivar ivar) * @note \c object_setIvar is faster than \c object_setInstanceVariable if the Ivar * for the instance variable is already known. */ -OBJC_EXPORT void object_setIvar(id obj, Ivar ivar, id value) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +object_setIvar(id _Nullable obj, Ivar _Nonnull ivar, id _Nullable value) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Sets the value of an instance variable in an object. @@ -195,8 +201,10 @@ OBJC_EXPORT void object_setIvar(id obj, Ivar ivar, id value) * @note \c object_setIvar is faster than \c object_setInstanceVariable if the Ivar * for the instance variable is already known. */ -OBJC_EXPORT void object_setIvarWithStrongDefault(id obj, Ivar ivar, id value) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); +OBJC_EXPORT void +object_setIvarWithStrongDefault(id _Nullable obj, Ivar _Nonnull ivar, + id _Nullable value) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); /** * Changes the value of an instance variable of a class instance. @@ -213,8 +221,10 @@ OBJC_EXPORT void object_setIvarWithStrongDefault(id obj, Ivar ivar, id value) * use that memory management. Instance variables with unknown memory management * are assigned as if they were unsafe_unretained. */ -OBJC_EXPORT Ivar object_setInstanceVariable(id obj, const char *name, void *value) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) +OBJC_EXPORT Ivar _Nullable +object_setInstanceVariable(id _Nullable obj, const char * _Nonnull name, + void * _Nullable value) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) OBJC_ARC_UNAVAILABLE; /** @@ -232,8 +242,11 @@ OBJC_EXPORT Ivar object_setInstanceVariable(id obj, const char *name, void *valu * use that memory management. Instance variables with unknown memory management * are assigned as if they were strong. */ -OBJC_EXPORT Ivar object_setInstanceVariableWithStrongDefault(id obj, const char *name, void *value) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0) +OBJC_EXPORT Ivar _Nullable +object_setInstanceVariableWithStrongDefault(id _Nullable obj, + const char * _Nonnull name, + void * _Nullable value) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0) OBJC_ARC_UNAVAILABLE; /** @@ -247,8 +260,10 @@ OBJC_EXPORT Ivar object_setInstanceVariableWithStrongDefault(id obj, const char * @return A pointer to the \c Ivar data structure that defines the type and name of * the instance variable specified by \e name. */ -OBJC_EXPORT Ivar object_getInstanceVariable(id obj, const char *name, void **outValue) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) +OBJC_EXPORT Ivar _Nullable +object_getInstanceVariable(id _Nullable obj, const char * _Nonnull name, + void * _Nullable * _Nullable outValue) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0) OBJC_ARC_UNAVAILABLE; @@ -270,8 +285,9 @@ OBJC_EXPORT Ivar object_getInstanceVariable(id obj, const char *name, void **out * @warning Earlier implementations of this function (prior to OS X v10.0) * terminate the program if the class does not exist. */ -OBJC_EXPORT Class objc_getClass(const char *name) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT Class _Nullable +objc_getClass(const char * _Nonnull name) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Returns the metaclass definition of a specified class. @@ -286,8 +302,9 @@ OBJC_EXPORT Class objc_getClass(const char *name) * definition must have a valid metaclass definition, and so the metaclass definition is always returned, * whether it’s valid or not. */ -OBJC_EXPORT Class objc_getMetaClass(const char *name) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT Class _Nullable +objc_getMetaClass(const char * _Nonnull name) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Returns the class definition of a specified class. @@ -301,8 +318,9 @@ OBJC_EXPORT Class objc_getMetaClass(const char *name) * registered, \c objc_getClass calls the class handler callback and then checks a second * time to see whether the class is registered. This function does not call the class handler callback. */ -OBJC_EXPORT Class objc_lookUpClass(const char *name) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT Class _Nullable +objc_lookUpClass(const char * _Nonnull name) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Returns the class definition of a specified class. @@ -314,8 +332,9 @@ OBJC_EXPORT Class objc_lookUpClass(const char *name) * @note This function is the same as \c objc_getClass, but kills the process if the class is not found. * @note This function is used by ZeroLink, where failing to find a class would be a compile-time link error without ZeroLink. */ -OBJC_EXPORT Class objc_getRequiredClass(const char *name) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT Class _Nonnull +objc_getRequiredClass(const char * _Nonnull name) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Obtains the list of registered class definitions. @@ -336,8 +355,9 @@ OBJC_EXPORT Class objc_getRequiredClass(const char *name) * @warning You cannot assume that class objects you get from this function are classes that inherit from \c NSObject, * so you cannot safely call any methods on such classes without detecting that the method is implemented first. */ -OBJC_EXPORT int objc_getClassList(Class *buffer, int bufferCount) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT int +objc_getClassList(Class _Nonnull * _Nullable buffer, int bufferCount) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Creates and returns a list of pointers to all registered class definitions. @@ -349,8 +369,9 @@ OBJC_EXPORT int objc_getClassList(Class *buffer, int bufferCount) * * @see objc_getClassList */ -OBJC_EXPORT Class *objc_copyClassList(unsigned int *outCount) - OBJC_AVAILABLE(10.7, 3.1, 9.0, 1.0); +OBJC_EXPORT Class _Nonnull * _Nullable +objc_copyClassList(unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.7, 3.1, 9.0, 1.0, 2.0); /* Working with Classes */ @@ -362,8 +383,9 @@ OBJC_EXPORT Class *objc_copyClassList(unsigned int *outCount) * * @return The name of the class, or the empty string if \e cls is \c Nil. */ -OBJC_EXPORT const char *class_getName(Class cls) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nonnull +class_getName(Class _Nullable cls) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns a Boolean value that indicates whether a class object is a metaclass. @@ -373,8 +395,9 @@ OBJC_EXPORT const char *class_getName(Class cls) * @return \c YES if \e cls is a metaclass, \c NO if \e cls is a non-meta class, * \c NO if \e cls is \c Nil. */ -OBJC_EXPORT BOOL class_isMetaClass(Class cls) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT BOOL +class_isMetaClass(Class _Nullable cls) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the superclass of a class. @@ -386,8 +409,9 @@ OBJC_EXPORT BOOL class_isMetaClass(Class cls) * * @note You should usually use \c NSObject's \c superclass method instead of this function. */ -OBJC_EXPORT Class class_getSuperclass(Class cls) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Class _Nullable +class_getSuperclass(Class _Nullable cls) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Sets the superclass of a given class. @@ -399,11 +423,13 @@ OBJC_EXPORT Class class_getSuperclass(Class cls) * * @warning You should not use this function. */ -OBJC_EXPORT Class class_setSuperclass(Class cls, Class newSuper) +OBJC_EXPORT Class _Nonnull +class_setSuperclass(Class _Nonnull cls, Class _Nonnull newSuper) __OSX_DEPRECATED(10.5, 10.5, "not recommended") __IOS_DEPRECATED(2.0, 2.0, "not recommended") __TVOS_DEPRECATED(9.0, 9.0, "not recommended") - __WATCHOS_DEPRECATED(1.0, 1.0, "not recommended"); + __WATCHOS_DEPRECATED(1.0, 1.0, "not recommended") + __BRIDGEOS_DEPRECATED(2.0, 2.0, "not recommended"); /** * Returns the version number of a class definition. @@ -415,8 +441,9 @@ OBJC_EXPORT Class class_setSuperclass(Class cls, Class newSuper) * * @see class_setVersion */ -OBJC_EXPORT int class_getVersion(Class cls) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT int +class_getVersion(Class _Nullable cls) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Sets the version number of a class definition. @@ -432,8 +459,9 @@ OBJC_EXPORT int class_getVersion(Class cls) * @note Classes derived from the Foundation framework \c NSObject class can set the class-definition * version number using the \c setVersion: class method, which is implemented using the \c class_setVersion function. */ -OBJC_EXPORT void class_setVersion(Class cls, int version) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT void +class_setVersion(Class _Nullable cls, int version) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Returns the size of instances of a class. @@ -442,8 +470,9 @@ OBJC_EXPORT void class_setVersion(Class cls, int version) * * @return The size in bytes of instances of the class \e cls, or \c 0 if \e cls is \c Nil. */ -OBJC_EXPORT size_t class_getInstanceSize(Class cls) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT size_t +class_getInstanceSize(Class _Nullable cls) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the \c Ivar for a specified instance variable of a given class. @@ -454,8 +483,9 @@ OBJC_EXPORT size_t class_getInstanceSize(Class cls) * @return A pointer to an \c Ivar data structure containing information about * the instance variable specified by \e name. */ -OBJC_EXPORT Ivar class_getInstanceVariable(Class cls, const char *name) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT Ivar _Nullable +class_getInstanceVariable(Class _Nullable cls, const char * _Nonnull name) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Returns the Ivar for a specified class variable of a given class. @@ -465,8 +495,9 @@ OBJC_EXPORT Ivar class_getInstanceVariable(Class cls, const char *name) * * @return A pointer to an \c Ivar data structure containing information about the class variable specified by \e name. */ -OBJC_EXPORT Ivar class_getClassVariable(Class cls, const char *name) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Ivar _Nullable +class_getClassVariable(Class _Nullable cls, const char * _Nonnull name) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Describes the instance variables declared by a class. @@ -481,8 +512,9 @@ OBJC_EXPORT Ivar class_getClassVariable(Class cls, const char *name) * * If the class declares no instance variables, or cls is Nil, NULL is returned and *outCount is 0. */ -OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Ivar _Nonnull * _Nullable +class_copyIvarList(Class _Nullable cls, unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns a specified instance method for a given class. @@ -496,8 +528,9 @@ OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount) * * @note This function searches superclasses for implementations, whereas \c class_copyMethodList does not. */ -OBJC_EXPORT Method class_getInstanceMethod(Class cls, SEL name) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT Method _Nullable +class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Returns a pointer to the data structure describing a given class method for a given class. @@ -512,8 +545,9 @@ OBJC_EXPORT Method class_getInstanceMethod(Class cls, SEL name) * @note Note that this function searches superclasses for implementations, * whereas \c class_copyMethodList does not. */ -OBJC_EXPORT Method class_getClassMethod(Class cls, SEL name) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT Method _Nullable +class_getClassMethod(Class _Nullable cls, SEL _Nonnull name) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Returns the function pointer that would be called if a @@ -530,8 +564,9 @@ OBJC_EXPORT Method class_getClassMethod(Class cls, SEL name) * an actual method implementation. For example, if instances of the class do not respond to * the selector, the function pointer returned will be part of the runtime's message forwarding machinery. */ -OBJC_EXPORT IMP class_getMethodImplementation(Class cls, SEL name) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT IMP _Nullable +class_getMethodImplementation(Class _Nullable cls, SEL _Nonnull name) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the function pointer that would be called if a particular @@ -543,8 +578,9 @@ OBJC_EXPORT IMP class_getMethodImplementation(Class cls, SEL name) * @return The function pointer that would be called if \c [object name] were called * with an instance of the class, or \c NULL if \e cls is \c Nil. */ -OBJC_EXPORT IMP class_getMethodImplementation_stret(Class cls, SEL name) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0) +OBJC_EXPORT IMP _Nullable +class_getMethodImplementation_stret(Class _Nullable cls, SEL _Nonnull name) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0) OBJC_ARM64_UNAVAILABLE; /** @@ -558,8 +594,9 @@ OBJC_EXPORT IMP class_getMethodImplementation_stret(Class cls, SEL name) * @note You should usually use \c NSObject's \c respondsToSelector: or \c instancesRespondToSelector: * methods instead of this function. */ -OBJC_EXPORT BOOL class_respondsToSelector(Class cls, SEL sel) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT BOOL +class_respondsToSelector(Class _Nullable cls, SEL _Nonnull sel) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Describes the instance methods implemented by a class. @@ -578,8 +615,9 @@ OBJC_EXPORT BOOL class_respondsToSelector(Class cls, SEL sel) * @note To get the implementations of methods that may be implemented by superclasses, * use \c class_getInstanceMethod or \c class_getClassMethod. */ -OBJC_EXPORT Method *class_copyMethodList(Class cls, unsigned int *outCount) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Method _Nonnull * _Nullable +class_copyMethodList(Class _Nullable cls, unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns a Boolean value that indicates whether a class conforms to a given protocol. @@ -591,8 +629,9 @@ OBJC_EXPORT Method *class_copyMethodList(Class cls, unsigned int *outCount) * * @note You should usually use NSObject's conformsToProtocol: method instead of this function. */ -OBJC_EXPORT BOOL class_conformsToProtocol(Class cls, Protocol *protocol) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT BOOL +class_conformsToProtocol(Class _Nullable cls, Protocol * _Nullable protocol) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Describes the protocols adopted by a class. @@ -607,8 +646,9 @@ OBJC_EXPORT BOOL class_conformsToProtocol(Class cls, Protocol *protocol) * * If cls adopts no protocols, or cls is Nil, returns NULL and *outCount is 0. */ -OBJC_EXPORT Protocol * __unsafe_unretained *class_copyProtocolList(Class cls, unsigned int *outCount) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Protocol * __unsafe_unretained _Nonnull * _Nullable +class_copyProtocolList(Class _Nullable cls, unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns a property with a given name of a given class. @@ -620,8 +660,9 @@ OBJC_EXPORT Protocol * __unsafe_unretained *class_copyProtocolList(Class cls, un * \c NULL if the class does not declare a property with that name, * or \c NULL if \e cls is \c Nil. */ -OBJC_EXPORT objc_property_t class_getProperty(Class cls, const char *name) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT objc_property_t _Nullable +class_getProperty(Class _Nullable cls, const char * _Nonnull name) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Describes the properties declared by a class. @@ -636,8 +677,9 @@ OBJC_EXPORT objc_property_t class_getProperty(Class cls, const char *name) * * If \e cls declares no properties, or \e cls is \c Nil, returns \c NULL and \c *outCount is \c 0. */ -OBJC_EXPORT objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT objc_property_t _Nonnull * _Nullable +class_copyPropertyList(Class _Nullable cls, unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns a description of the \c Ivar layout for a given class. @@ -646,8 +688,9 @@ OBJC_EXPORT objc_property_t *class_copyPropertyList(Class cls, unsigned int *out * * @return A description of the \c Ivar layout for \e cls. */ -OBJC_EXPORT const uint8_t *class_getIvarLayout(Class cls) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const uint8_t * _Nullable +class_getIvarLayout(Class _Nullable cls) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns a description of the layout of weak Ivars for a given class. @@ -656,8 +699,9 @@ OBJC_EXPORT const uint8_t *class_getIvarLayout(Class cls) * * @return A description of the layout of the weak \c Ivars for \e cls. */ -OBJC_EXPORT const uint8_t *class_getWeakIvarLayout(Class cls) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const uint8_t * _Nullable +class_getWeakIvarLayout(Class _Nullable cls) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Adds a new method to a class with a given name and implementation. @@ -674,9 +718,10 @@ OBJC_EXPORT const uint8_t *class_getWeakIvarLayout(Class cls) * but will not replace an existing implementation in this class. * To change an existing implementation, use method_setImplementation. */ -OBJC_EXPORT BOOL class_addMethod(Class cls, SEL name, IMP imp, - const char *types) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT BOOL +class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, + const char * _Nullable types) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Replaces the implementation of a method for a given class. @@ -696,9 +741,10 @@ OBJC_EXPORT BOOL class_addMethod(Class cls, SEL name, IMP imp, * - If the method identified by \e name does exist, its \c IMP is replaced as if \c method_setImplementation were called. * The type encoding specified by \e types is ignored. */ -OBJC_EXPORT IMP class_replaceMethod(Class cls, SEL name, IMP imp, - const char *types) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT IMP _Nullable +class_replaceMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, + const char * _Nullable types) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Adds a new instance variable to a class. @@ -713,9 +759,10 @@ OBJC_EXPORT IMP class_replaceMethod(Class cls, SEL name, IMP imp, * variable depends on the ivar's type and the machine architecture. * For variables of any pointer type, pass log2(sizeof(pointer_type)). */ -OBJC_EXPORT BOOL class_addIvar(Class cls, const char *name, size_t size, - uint8_t alignment, const char *types) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT BOOL +class_addIvar(Class _Nullable cls, const char * _Nonnull name, size_t size, + uint8_t alignment, const char * _Nullable types) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Adds a protocol to a class. @@ -726,8 +773,9 @@ OBJC_EXPORT BOOL class_addIvar(Class cls, const char *name, size_t size, * @return \c YES if the method was added successfully, otherwise \c NO * (for example, the class already conforms to that protocol). */ -OBJC_EXPORT BOOL class_addProtocol(Class cls, Protocol *protocol) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT BOOL +class_addProtocol(Class _Nullable cls, Protocol * _Nonnull protocol) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Adds a property to a class. @@ -740,8 +788,11 @@ OBJC_EXPORT BOOL class_addProtocol(Class cls, Protocol *protocol) * @return \c YES if the property was added successfully, otherwise \c NO * (for example, the class already has that property). */ -OBJC_EXPORT BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT BOOL +class_addProperty(Class _Nullable cls, const char * _Nonnull name, + const objc_property_attribute_t * _Nullable attributes, + unsigned int attributeCount) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /** * Replace a property of a class. @@ -751,8 +802,11 @@ OBJC_EXPORT BOOL class_addProperty(Class cls, const char *name, const objc_prope * @param attributes An array of property attributes. * @param attributeCount The number of attributes in \e attributes. */ -OBJC_EXPORT void class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT void +class_replaceProperty(Class _Nullable cls, const char * _Nonnull name, + const objc_property_attribute_t * _Nullable attributes, + unsigned int attributeCount) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /** * Sets the Ivar layout for a given class. @@ -760,8 +814,9 @@ OBJC_EXPORT void class_replaceProperty(Class cls, const char *name, const objc_p * @param cls The class to modify. * @param layout The layout of the \c Ivars for \e cls. */ -OBJC_EXPORT void class_setIvarLayout(Class cls, const uint8_t *layout) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +class_setIvarLayout(Class _Nullable cls, const uint8_t * _Nullable layout) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Sets the layout for weak Ivars for a given class. @@ -769,8 +824,9 @@ OBJC_EXPORT void class_setIvarLayout(Class cls, const uint8_t *layout) * @param cls The class to modify. * @param layout The layout of the weak Ivars for \e cls. */ -OBJC_EXPORT void class_setWeakIvarLayout(Class cls, const uint8_t *layout) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +class_setWeakIvarLayout(Class _Nullable cls, const uint8_t * _Nullable layout) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Used by CoreFoundation's toll-free bridging. @@ -782,8 +838,9 @@ OBJC_EXPORT void class_setWeakIvarLayout(Class cls, const uint8_t *layout) * * @warning Do not call this function yourself. */ -OBJC_EXPORT Class objc_getFutureClass(const char *name) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0) +OBJC_EXPORT Class _Nonnull +objc_getFutureClass(const char * _Nonnull name) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0) OBJC_ARC_UNAVAILABLE; @@ -800,9 +857,10 @@ OBJC_EXPORT Class objc_getFutureClass(const char *name) * * @return An instance of the class \e cls. */ -OBJC_EXPORT id class_createInstance(Class cls, size_t extraBytes) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) - OBJC_ARC_UNAVAILABLE; +OBJC_EXPORT id _Nullable +class_createInstance(Class _Nullable cls, size_t extraBytes) + OBJC_RETURNS_RETAINED + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Creates an instance of a class at the specific location provided. @@ -817,8 +875,9 @@ OBJC_EXPORT id class_createInstance(Class cls, size_t extraBytes) * * @see class_createInstance */ -OBJC_EXPORT id objc_constructInstance(Class cls, void *bytes) - OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0) +OBJC_EXPORT id _Nullable +objc_constructInstance(Class _Nullable cls, void * _Nullable bytes) + OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0) OBJC_ARC_UNAVAILABLE; /** @@ -831,8 +890,8 @@ OBJC_EXPORT id objc_constructInstance(Class cls, void *bytes) * * @note CF and other clients do call this under GC. */ -OBJC_EXPORT void *objc_destructInstance(id obj) - OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0) +OBJC_EXPORT void * _Nullable objc_destructInstance(id _Nullable obj) + OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0) OBJC_ARC_UNAVAILABLE; @@ -855,25 +914,29 @@ OBJC_EXPORT void *objc_destructInstance(id obj) * @note Instance methods and instance variables should be added to the class itself. * Class methods should be added to the metaclass. */ -OBJC_EXPORT Class objc_allocateClassPair(Class superclass, const char *name, - size_t extraBytes) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Class _Nullable +objc_allocateClassPair(Class _Nullable superclass, const char * _Nonnull name, + size_t extraBytes) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Registers a class that was allocated using \c objc_allocateClassPair. * * @param cls The class you want to register. */ -OBJC_EXPORT void objc_registerClassPair(Class cls) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +objc_registerClassPair(Class _Nonnull cls) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Used by Foundation's Key-Value Observing. * * @warning Do not call this function yourself. */ -OBJC_EXPORT Class objc_duplicateClass(Class original, const char *name, size_t extraBytes) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Class _Nonnull +objc_duplicateClass(Class _Nonnull original, const char * _Nonnull name, + size_t extraBytes) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Destroy a class and its associated metaclass. @@ -883,8 +946,9 @@ OBJC_EXPORT Class objc_duplicateClass(Class original, const char *name, size_t e * * @warning Do not call if instances of this class or a subclass exist. */ -OBJC_EXPORT void objc_disposeClassPair(Class cls) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +objc_disposeClassPair(Class _Nonnull cls) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /* Working with Methods */ @@ -898,8 +962,9 @@ OBJC_EXPORT void objc_disposeClassPair(Class cls) * * @note To get the method name as a C string, call \c sel_getName(method_getName(method)). */ -OBJC_EXPORT SEL method_getName(Method m) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT SEL _Nonnull +method_getName(Method _Nonnull m) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the implementation of a method. @@ -908,8 +973,9 @@ OBJC_EXPORT SEL method_getName(Method m) * * @return A function pointer of type IMP. */ -OBJC_EXPORT IMP method_getImplementation(Method m) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT IMP _Nonnull +method_getImplementation(Method _Nonnull m) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns a string describing a method's parameter and return types. @@ -918,8 +984,9 @@ OBJC_EXPORT IMP method_getImplementation(Method m) * * @return A C string. The string may be \c NULL. */ -OBJC_EXPORT const char *method_getTypeEncoding(Method m) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nullable +method_getTypeEncoding(Method _Nonnull m) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the number of arguments accepted by a method. @@ -928,8 +995,9 @@ OBJC_EXPORT const char *method_getTypeEncoding(Method m) * * @return An integer containing the number of arguments accepted by the given method. */ -OBJC_EXPORT unsigned int method_getNumberOfArguments(Method m) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT unsigned int +method_getNumberOfArguments(Method _Nonnull m) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Returns a string describing a method's return type. @@ -938,8 +1006,9 @@ OBJC_EXPORT unsigned int method_getNumberOfArguments(Method m) * * @return A C string describing the return type. You must free the string with \c free(). */ -OBJC_EXPORT char *method_copyReturnType(Method m) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT char * _Nonnull +method_copyReturnType(Method _Nonnull m) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns a string describing a single parameter type of a method. @@ -950,8 +1019,9 @@ OBJC_EXPORT char *method_copyReturnType(Method m) * @return A C string describing the type of the parameter at index \e index, or \c NULL * if method has no parameter index \e index. You must free the string with \c free(). */ -OBJC_EXPORT char *method_copyArgumentType(Method m, unsigned int index) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT char * _Nullable +method_copyArgumentType(Method _Nonnull m, unsigned int index) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns by reference a string describing a method's return type. @@ -963,8 +1033,9 @@ OBJC_EXPORT char *method_copyArgumentType(Method m, unsigned int index) * @note The method's return type string is copied to \e dst. * \e dst is filled as if \c strncpy(dst, parameter_type, dst_len) were called. */ -OBJC_EXPORT void method_getReturnType(Method m, char *dst, size_t dst_len) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +method_getReturnType(Method _Nonnull m, char * _Nonnull dst, size_t dst_len) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns by reference a string describing a single parameter type of a method. @@ -978,11 +1049,14 @@ OBJC_EXPORT void method_getReturnType(Method m, char *dst, size_t dst_len) * were called. If the method contains no parameter with that index, \e dst is filled as * if \c strncpy(dst, "", dst_len) were called. */ -OBJC_EXPORT void method_getArgumentType(Method m, unsigned int index, - char *dst, size_t dst_len) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); -OBJC_EXPORT struct objc_method_description *method_getDescription(Method m) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +method_getArgumentType(Method _Nonnull m, unsigned int index, + char * _Nullable dst, size_t dst_len) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); + +OBJC_EXPORT struct objc_method_description * _Nonnull +method_getDescription(Method _Nonnull m) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Sets the implementation of a method. @@ -992,8 +1066,9 @@ OBJC_EXPORT struct objc_method_description *method_getDescription(Method m) * * @return The previous implementation of the method. */ -OBJC_EXPORT IMP method_setImplementation(Method m, IMP imp) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT IMP _Nonnull +method_setImplementation(Method _Nonnull m, IMP _Nonnull imp) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Exchanges the implementations of two methods. @@ -1009,8 +1084,9 @@ OBJC_EXPORT IMP method_setImplementation(Method m, IMP imp) * method_setImplementation(m2, imp1); * \endcode */ -OBJC_EXPORT void method_exchangeImplementations(Method m1, Method m2) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /* Working with Instance Variables */ @@ -1022,8 +1098,9 @@ OBJC_EXPORT void method_exchangeImplementations(Method m1, Method m2) * * @return A C string containing the instance variable's name. */ -OBJC_EXPORT const char *ivar_getName(Ivar v) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nullable +ivar_getName(Ivar _Nonnull v) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the type string of an instance variable. @@ -1034,8 +1111,9 @@ OBJC_EXPORT const char *ivar_getName(Ivar v) * * @note For possible values, see Objective-C Runtime Programming Guide > Type Encodings. */ -OBJC_EXPORT const char *ivar_getTypeEncoding(Ivar v) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nullable +ivar_getTypeEncoding(Ivar _Nonnull v) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the offset of an instance variable. @@ -1047,8 +1125,9 @@ OBJC_EXPORT const char *ivar_getTypeEncoding(Ivar v) * @note For instance variables of type \c id or other object types, call \c object_getIvar * and \c object_setIvar instead of using this offset to access the instance variable data directly. */ -OBJC_EXPORT ptrdiff_t ivar_getOffset(Ivar v) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT ptrdiff_t +ivar_getOffset(Ivar _Nonnull v) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /* Working with Properties */ @@ -1060,8 +1139,9 @@ OBJC_EXPORT ptrdiff_t ivar_getOffset(Ivar v) * * @return A C string containing the property's name. */ -OBJC_EXPORT const char *property_getName(objc_property_t property) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nonnull +property_getName(objc_property_t _Nonnull property) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the attribute string of a property. @@ -1072,8 +1152,9 @@ OBJC_EXPORT const char *property_getName(objc_property_t property) * * @note The format of the attribute string is described in Declared Properties in Objective-C Runtime Programming Guide. */ -OBJC_EXPORT const char *property_getAttributes(objc_property_t property) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nullable +property_getAttributes(objc_property_t _Nonnull property) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns an array of property attributes for a property. @@ -1083,8 +1164,10 @@ OBJC_EXPORT const char *property_getAttributes(objc_property_t property) * * @return An array of property attributes; must be free'd() by the caller. */ -OBJC_EXPORT objc_property_attribute_t *property_copyAttributeList(objc_property_t property, unsigned int *outCount) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT objc_property_attribute_t * _Nullable +property_copyAttributeList(objc_property_t _Nonnull property, + unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /** * Returns the value of a property attribute given the attribute name. @@ -1095,8 +1178,10 @@ OBJC_EXPORT objc_property_attribute_t *property_copyAttributeList(objc_property_ * @return The value string of the attribute \e attributeName if it exists in * \e property, \c nil otherwise. */ -OBJC_EXPORT char *property_copyAttributeValue(objc_property_t property, const char *attributeName) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT char * _Nullable +property_copyAttributeValue(objc_property_t _Nonnull property, + const char * _Nonnull attributeName) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /* Working with Protocols */ @@ -1110,8 +1195,9 @@ OBJC_EXPORT char *property_copyAttributeValue(objc_property_t property, const ch * * @note This function acquires the runtime lock. */ -OBJC_EXPORT Protocol *objc_getProtocol(const char *name) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Protocol * _Nullable +objc_getProtocol(const char * _Nonnull name) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns an array of all the protocols known to the runtime. @@ -1123,8 +1209,9 @@ OBJC_EXPORT Protocol *objc_getProtocol(const char *name) * * @note This function acquires the runtime lock. */ -OBJC_EXPORT Protocol * __unsafe_unretained *objc_copyProtocolList(unsigned int *outCount) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Protocol * __unsafe_unretained _Nonnull * _Nullable +objc_copyProtocolList(unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns a Boolean value that indicates whether one protocol conforms to another protocol. @@ -1141,8 +1228,10 @@ OBJC_EXPORT Protocol * __unsafe_unretained *objc_copyProtocolList(unsigned int * * \endcode * All the protocols listed between angle brackets are considered part of the ProtocolName protocol. */ -OBJC_EXPORT BOOL protocol_conformsToProtocol(Protocol *proto, Protocol *other) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT BOOL +protocol_conformsToProtocol(Protocol * _Nullable proto, + Protocol * _Nullable other) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns a Boolean value that indicates whether two protocols are equal. @@ -1152,8 +1241,9 @@ OBJC_EXPORT BOOL protocol_conformsToProtocol(Protocol *proto, Protocol *other) * * @return \c YES if \e proto is the same as \e other, otherwise \c NO. */ -OBJC_EXPORT BOOL protocol_isEqual(Protocol *proto, Protocol *other) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT BOOL +protocol_isEqual(Protocol * _Nullable proto, Protocol * _Nullable other) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the name of a protocol. @@ -1162,8 +1252,9 @@ OBJC_EXPORT BOOL protocol_isEqual(Protocol *proto, Protocol *other) * * @return The name of the protocol \e p as a C string. */ -OBJC_EXPORT const char *protocol_getName(Protocol *p) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nonnull +protocol_getName(Protocol * _Nonnull proto) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns a method description structure for a specified method of a given protocol. @@ -1180,8 +1271,10 @@ OBJC_EXPORT const char *protocol_getName(Protocol *p) * * @note This function recursively searches any protocols that this protocol conforms to. */ -OBJC_EXPORT struct objc_method_description protocol_getMethodDescription(Protocol *p, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT struct objc_method_description +protocol_getMethodDescription(Protocol * _Nonnull proto, SEL _Nonnull aSel, + BOOL isRequiredMethod, BOOL isInstanceMethod) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns an array of method descriptions of methods meeting a given specification for a given protocol. @@ -1200,8 +1293,12 @@ OBJC_EXPORT struct objc_method_description protocol_getMethodDescription(Protoco * * @note Methods in other protocols adopted by this protocol are not included. */ -OBJC_EXPORT struct objc_method_description *protocol_copyMethodDescriptionList(Protocol *p, BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *outCount) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT struct objc_method_description * _Nullable +protocol_copyMethodDescriptionList(Protocol * _Nonnull proto, + BOOL isRequiredMethod, + BOOL isInstanceMethod, + unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the specified property of a given protocol. @@ -1214,8 +1311,11 @@ OBJC_EXPORT struct objc_method_description *protocol_copyMethodDescriptionList(P * @return The property specified by \e name, \e isRequiredProperty, and \e isInstanceProperty for \e proto, * or \c NULL if none of \e proto's properties meets the specification. */ -OBJC_EXPORT objc_property_t protocol_getProperty(Protocol *proto, const char *name, BOOL isRequiredProperty, BOOL isInstanceProperty) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT objc_property_t _Nullable +protocol_getProperty(Protocol * _Nonnull proto, + const char * _Nonnull name, + BOOL isRequiredProperty, BOOL isInstanceProperty) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns an array of the required instance properties declared by a protocol. @@ -1225,8 +1325,10 @@ OBJC_EXPORT objc_property_t protocol_getProperty(Protocol *proto, const char *na * protocol_copyPropertyList2(proto, outCount, YES, YES); * \endcode */ -OBJC_EXPORT objc_property_t *protocol_copyPropertyList(Protocol *proto, unsigned int *outCount) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT objc_property_t _Nonnull * _Nullable +protocol_copyPropertyList(Protocol * _Nonnull proto, + unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns an array of properties declared by a protocol. @@ -1241,8 +1343,11 @@ OBJC_EXPORT objc_property_t *protocol_copyPropertyList(Protocol *proto, unsigned * \c *outCount pointers followed by a \c NULL terminator. You must free the array with \c free(). * If the protocol declares no matching properties, \c NULL is returned and \c *outCount is \c 0. */ -OBJC_EXPORT objc_property_t *protocol_copyPropertyList2(Protocol *proto, unsigned int *outCount, BOOL isRequiredProperty, BOOL isInstanceProperty) - OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); +OBJC_EXPORT objc_property_t _Nonnull * _Nullable +protocol_copyPropertyList2(Protocol * _Nonnull proto, + unsigned int * _Nullable outCount, + BOOL isRequiredProperty, BOOL isInstanceProperty) + OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0); /** * Returns an array of the protocols adopted by a protocol. @@ -1254,8 +1359,10 @@ OBJC_EXPORT objc_property_t *protocol_copyPropertyList2(Protocol *proto, unsigne * followed by a \c NULL terminator. You must free the array with \c free(). * If the protocol declares no properties, \c NULL is returned and \c *outCount is \c 0. */ -OBJC_EXPORT Protocol * __unsafe_unretained *protocol_copyProtocolList(Protocol *proto, unsigned int *outCount) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT Protocol * __unsafe_unretained _Nonnull * _Nullable +protocol_copyProtocolList(Protocol * _Nonnull proto, + unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Creates a new protocol instance that cannot be used until registered with @@ -1267,8 +1374,9 @@ OBJC_EXPORT Protocol * __unsafe_unretained *protocol_copyProtocolList(Protocol * * with the same name already exists. * @note There is no dispose method for this. */ -OBJC_EXPORT Protocol *objc_allocateProtocol(const char *name) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT Protocol * _Nullable +objc_allocateProtocol(const char * _Nonnull name) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /** * Registers a newly constructed protocol with the runtime. The protocol @@ -1276,8 +1384,9 @@ OBJC_EXPORT Protocol *objc_allocateProtocol(const char *name) * * @param proto The protocol you want to register. */ -OBJC_EXPORT void objc_registerProtocol(Protocol *proto) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT void +objc_registerProtocol(Protocol * _Nonnull proto) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /** * Adds a method to a protocol. The protocol must be under construction. @@ -1288,8 +1397,11 @@ OBJC_EXPORT void objc_registerProtocol(Protocol *proto) * @param isRequiredMethod YES if the method is not an optional method. * @param isInstanceMethod YES if the method is an instance method. */ -OBJC_EXPORT void protocol_addMethodDescription(Protocol *proto, SEL name, const char *types, BOOL isRequiredMethod, BOOL isInstanceMethod) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT void +protocol_addMethodDescription(Protocol * _Nonnull proto, SEL _Nonnull name, + const char * _Nullable types, + BOOL isRequiredMethod, BOOL isInstanceMethod) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /** * Adds an incorporated protocol to another protocol. The protocol being @@ -1299,8 +1411,9 @@ OBJC_EXPORT void protocol_addMethodDescription(Protocol *proto, SEL name, const * @param proto The protocol you want to add to, it must be under construction. * @param addition The protocol you want to incorporate into \e proto, it must be registered. */ -OBJC_EXPORT void protocol_addProtocol(Protocol *proto, Protocol *addition) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT void +protocol_addProtocol(Protocol * _Nonnull proto, Protocol * _Nonnull addition) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /** * Adds a property to a protocol. The protocol must be under construction. @@ -1314,8 +1427,12 @@ OBJC_EXPORT void protocol_addProtocol(Protocol *proto, Protocol *addition) * This is the only case allowed fo a property, as a result, setting this to NO will * not add the property to the protocol at all. */ -OBJC_EXPORT void protocol_addProperty(Protocol *proto, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount, BOOL isRequiredProperty, BOOL isInstanceProperty) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT void +protocol_addProperty(Protocol * _Nonnull proto, const char * _Nonnull name, + const objc_property_attribute_t * _Nullable attributes, + unsigned int attributeCount, + BOOL isRequiredProperty, BOOL isInstanceProperty) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /* Working with Libraries */ @@ -1328,8 +1445,9 @@ OBJC_EXPORT void protocol_addProperty(Protocol *proto, const char *name, const o * * @return An array of C strings of names. Must be free()'d by caller. */ -OBJC_EXPORT const char **objc_copyImageNames(unsigned int *outCount) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nonnull * _Nonnull +objc_copyImageNames(unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the dynamic library name a class originated from. @@ -1338,8 +1456,9 @@ OBJC_EXPORT const char **objc_copyImageNames(unsigned int *outCount) * * @return The name of the library containing this class. */ -OBJC_EXPORT const char *class_getImageName(Class cls) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nullable +class_getImageName(Class _Nullable cls) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Returns the names of all the classes within a library. @@ -1349,9 +1468,10 @@ OBJC_EXPORT const char *class_getImageName(Class cls) * * @return An array of C strings representing the class names. */ -OBJC_EXPORT const char **objc_copyClassNamesForImage(const char *image, - unsigned int *outCount) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nonnull * _Nullable +objc_copyClassNamesForImage(const char * _Nonnull image, + unsigned int * _Nullable outCount) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /* Working with Selectors */ @@ -1363,8 +1483,9 @@ OBJC_EXPORT const char **objc_copyClassNamesForImage(const char *image, * * @return A C string indicating the name of the selector. */ -OBJC_EXPORT const char *sel_getName(SEL sel) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT const char * _Nonnull +sel_getName(SEL _Nonnull sel) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** @@ -1379,8 +1500,9 @@ OBJC_EXPORT const char *sel_getName(SEL sel) * method’s selector before you can add the method to a class definition. If the method name * has already been registered, this function simply returns the selector. */ -OBJC_EXPORT SEL sel_registerName(const char *str) - OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); +OBJC_EXPORT SEL _Nonnull +sel_registerName(const char * _Nonnull str) + OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0); /** * Returns a Boolean value that indicates whether two selectors are equal. @@ -1392,8 +1514,9 @@ OBJC_EXPORT SEL sel_registerName(const char *str) * * @note sel_isEqual is equivalent to ==. */ -OBJC_EXPORT BOOL sel_isEqual(SEL lhs, SEL rhs) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT BOOL +sel_isEqual(SEL _Nonnull lhs, SEL _Nonnull rhs) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /* Objective-C Language Features */ @@ -1407,16 +1530,18 @@ OBJC_EXPORT BOOL sel_isEqual(SEL lhs, SEL rhs) * @param obj The object being mutated. * */ -OBJC_EXPORT void objc_enumerationMutation(id obj) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +objc_enumerationMutation(id _Nonnull obj) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Sets the current mutation handler. * * @param handler Function pointer to the new mutation handler. */ -OBJC_EXPORT void objc_setEnumerationMutationHandler(void (*handler)(id)) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +objc_setEnumerationMutationHandler(void (*_Nullable handler)(id _Nonnull )) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Set the function to be called by objc_msgForward. @@ -1426,8 +1551,9 @@ OBJC_EXPORT void objc_setEnumerationMutationHandler(void (*handler)(id)) * * @see message.h::_objc_msgForward */ -OBJC_EXPORT void objc_setForwardHandler(void *fwd, void *fwd_stret) - OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); +OBJC_EXPORT void +objc_setForwardHandler(void * _Nonnull fwd, void * _Nonnull fwd_stret) + OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); /** * Creates a pointer to a function that will call the block @@ -1441,8 +1567,9 @@ OBJC_EXPORT void objc_setForwardHandler(void *fwd, void *fwd_stret) * @return The IMP that calls this block. Must be disposed of with * \c imp_removeBlock. */ -OBJC_EXPORT IMP imp_implementationWithBlock(id block) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT IMP _Nonnull +imp_implementationWithBlock(id _Nonnull block) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /** * Return the block associated with an IMP that was created using @@ -1452,8 +1579,9 @@ OBJC_EXPORT IMP imp_implementationWithBlock(id block) * * @return The block called by \e anImp. */ -OBJC_EXPORT id imp_getBlock(IMP anImp) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT id _Nullable +imp_getBlock(IMP _Nonnull anImp) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /** * Disassociates a block from an IMP that was created using @@ -1465,8 +1593,9 @@ OBJC_EXPORT id imp_getBlock(IMP anImp) * @return YES if the block was released successfully, NO otherwise. * (For example, the block might not have been used to create an IMP previously). */ -OBJC_EXPORT BOOL imp_removeBlock(IMP anImp) - OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0); +OBJC_EXPORT BOOL +imp_removeBlock(IMP _Nonnull anImp) + OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0); /** * This loads the object referenced by a weak pointer and returns it, after @@ -1476,10 +1605,11 @@ OBJC_EXPORT BOOL imp_removeBlock(IMP anImp) * * @param location The weak pointer address * - * @return The object pointed to by \e location, or \c nil if \e location is \c nil. + * @return The object pointed to by \e location, or \c nil if \e *location is \c nil. */ -OBJC_EXPORT id objc_loadWeak(id *location) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_loadWeak(id _Nullable * _Nonnull location) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); /** * This function stores a new value into a __weak variable. It would @@ -1490,8 +1620,9 @@ OBJC_EXPORT id objc_loadWeak(id *location) * * @return The value stored into \e location, i.e. \e obj */ -OBJC_EXPORT id objc_storeWeak(id *location, id obj) - OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_storeWeak(id _Nullable * _Nonnull location, id _Nullable obj) + OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0); /* Associative References */ @@ -1523,8 +1654,10 @@ typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) { * @see objc_setAssociatedObject * @see objc_removeAssociatedObjects */ -OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) - OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0); +OBJC_EXPORT void +objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key, + id _Nullable value, objc_AssociationPolicy policy) + OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0); /** * Returns the value associated with a given object for a given key. @@ -1536,8 +1669,9 @@ OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, * * @see objc_setAssociatedObject */ -OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) - OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0); +OBJC_EXPORT id _Nullable +objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key) + OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0); /** * Removes all associations for a given object. @@ -1553,8 +1687,9 @@ OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) * @see objc_setAssociatedObject * @see objc_getAssociatedObject */ -OBJC_EXPORT void objc_removeAssociatedObjects(id object) - OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0); +OBJC_EXPORT void +objc_removeAssociatedObjects(id _Nonnull object) + OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0); #define _C_ID '@' @@ -1634,30 +1769,30 @@ OBJC_EXPORT void objc_removeAssociatedObjects(id object) struct objc_method_description_list { - int count; - struct objc_method_description list[1]; + int count; + struct objc_method_description list[1]; }; struct objc_protocol_list { - struct objc_protocol_list *next; + struct objc_protocol_list * _Nullable next; long count; - __unsafe_unretained Protocol *list[1]; + __unsafe_unretained Protocol * _Nullable list[1]; }; struct objc_category { - char *category_name OBJC2_UNAVAILABLE; - char *class_name OBJC2_UNAVAILABLE; - struct objc_method_list *instance_methods OBJC2_UNAVAILABLE; - struct objc_method_list *class_methods OBJC2_UNAVAILABLE; - struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; + char * _Nonnull category_name OBJC2_UNAVAILABLE; + char * _Nonnull class_name OBJC2_UNAVAILABLE; + struct objc_method_list * _Nullable instance_methods OBJC2_UNAVAILABLE; + struct objc_method_list * _Nullable class_methods OBJC2_UNAVAILABLE; + struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE; } OBJC2_UNAVAILABLE; struct objc_ivar { - char *ivar_name OBJC2_UNAVAILABLE; - char *ivar_type OBJC2_UNAVAILABLE; + char * _Nullable ivar_name OBJC2_UNAVAILABLE; + char * _Nullable ivar_type OBJC2_UNAVAILABLE; int ivar_offset OBJC2_UNAVAILABLE; #ifdef __LP64__ int space OBJC2_UNAVAILABLE; @@ -1675,13 +1810,13 @@ struct objc_ivar_list { struct objc_method { - SEL method_name OBJC2_UNAVAILABLE; - char *method_types OBJC2_UNAVAILABLE; - IMP method_imp OBJC2_UNAVAILABLE; + SEL _Nonnull method_name OBJC2_UNAVAILABLE; + char * _Nullable method_types OBJC2_UNAVAILABLE; + IMP _Nonnull method_imp OBJC2_UNAVAILABLE; } OBJC2_UNAVAILABLE; struct objc_method_list { - struct objc_method_list *obsolete OBJC2_UNAVAILABLE; + struct objc_method_list * _Nullable obsolete OBJC2_UNAVAILABLE; int method_count OBJC2_UNAVAILABLE; #ifdef __LP64__ @@ -1696,10 +1831,10 @@ typedef struct objc_symtab *Symtab OBJC2_UNAVAILABLE; struct objc_symtab { unsigned long sel_ref_cnt OBJC2_UNAVAILABLE; - SEL *refs OBJC2_UNAVAILABLE; + SEL _Nonnull * _Nullable refs OBJC2_UNAVAILABLE; unsigned short cls_def_cnt OBJC2_UNAVAILABLE; unsigned short cat_def_cnt OBJC2_UNAVAILABLE; - void *defs[1] /* variable size */ OBJC2_UNAVAILABLE; + void * _Nullable defs[1] /* variable size */ OBJC2_UNAVAILABLE; } OBJC2_UNAVAILABLE; @@ -1716,7 +1851,7 @@ typedef struct objc_cache *Cache OBJC2_UNAVAILABLE; struct objc_cache { unsigned int mask /* total = mask + 1 */ OBJC2_UNAVAILABLE; unsigned int occupied OBJC2_UNAVAILABLE; - Method buckets[1] OBJC2_UNAVAILABLE; + Method _Nullable buckets[1] OBJC2_UNAVAILABLE; }; @@ -1725,8 +1860,8 @@ typedef struct objc_module *Module OBJC2_UNAVAILABLE; struct objc_module { unsigned long version OBJC2_UNAVAILABLE; unsigned long size OBJC2_UNAVAILABLE; - const char *name OBJC2_UNAVAILABLE; - Symtab symtab OBJC2_UNAVAILABLE; + const char * _Nullable name OBJC2_UNAVAILABLE; + Symtab _Nullable symtab OBJC2_UNAVAILABLE; } OBJC2_UNAVAILABLE; #else @@ -1738,52 +1873,103 @@ struct objc_method_list; /* Obsolete functions */ -OBJC_EXPORT IMP class_lookupMethod(Class cls, SEL sel) +OBJC_EXPORT IMP _Nullable +class_lookupMethod(Class _Nullable cls, SEL _Nonnull sel) __OSX_DEPRECATED(10.0, 10.5, "use class_getMethodImplementation instead") __IOS_DEPRECATED(2.0, 2.0, "use class_getMethodImplementation instead") __TVOS_DEPRECATED(9.0, 9.0, "use class_getMethodImplementation instead") - __WATCHOS_DEPRECATED(1.0, 1.0, "use class_getMethodImplementation instead"); -OBJC_EXPORT BOOL class_respondsToMethod(Class cls, SEL sel) + __WATCHOS_DEPRECATED(1.0, 1.0, "use class_getMethodImplementation instead") + __BRIDGEOS_DEPRECATED(2.0, 2.0, "use class_getMethodImplementation instead"); +OBJC_EXPORT BOOL +class_respondsToMethod(Class _Nullable cls, SEL _Nonnull sel) __OSX_DEPRECATED(10.0, 10.5, "use class_respondsToSelector instead") __IOS_DEPRECATED(2.0, 2.0, "use class_respondsToSelector instead") __TVOS_DEPRECATED(9.0, 9.0, "use class_respondsToSelector instead") - __WATCHOS_DEPRECATED(1.0, 1.0, "use class_respondsToSelector instead"); -OBJC_EXPORT void _objc_flush_caches(Class cls) + __WATCHOS_DEPRECATED(1.0, 1.0, "use class_respondsToSelector instead") + __BRIDGEOS_DEPRECATED(2.0, 2.0, "use class_respondsToSelector instead"); + +OBJC_EXPORT void +_objc_flush_caches(Class _Nullable cls) __OSX_DEPRECATED(10.0, 10.5, "not recommended") __IOS_DEPRECATED(2.0, 2.0, "not recommended") __TVOS_DEPRECATED(9.0, 9.0, "not recommended") - __WATCHOS_DEPRECATED(1.0, 1.0, "not recommended"); + __WATCHOS_DEPRECATED(1.0, 1.0, "not recommended") + __BRIDGEOS_DEPRECATED(2.0, 2.0, "not recommended"); -OBJC_EXPORT id object_copyFromZone(id anObject, size_t nBytes, void *z) +OBJC_EXPORT id _Nullable +object_copyFromZone(id _Nullable anObject, size_t nBytes, void * _Nullable z) __OSX_DEPRECATED(10.0, 10.5, "use object_copy instead") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; -OBJC_EXPORT id object_realloc(id anObject, size_t nBytes) OBJC2_UNAVAILABLE; -OBJC_EXPORT id object_reallocFromZone(id anObject, size_t nBytes, void *z) OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +object_realloc(id _Nullable anObject, size_t nBytes) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +object_reallocFromZone(id _Nullable anObject, size_t nBytes, void * _Nullable z) + OBJC2_UNAVAILABLE; #define OBSOLETE_OBJC_GETCLASSES 1 -OBJC_EXPORT void *objc_getClasses(void) OBJC2_UNAVAILABLE; -OBJC_EXPORT void objc_addClass(Class myClass) OBJC2_UNAVAILABLE; -OBJC_EXPORT void objc_setClassHandler(int (*)(const char *)) OBJC2_UNAVAILABLE; -OBJC_EXPORT void objc_setMultithreaded (BOOL flag) OBJC2_UNAVAILABLE; +OBJC_EXPORT void * _Nonnull +objc_getClasses(void) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +objc_addClass(Class _Nonnull myClass) + OBJC2_UNAVAILABLE; -OBJC_EXPORT id class_createInstanceFromZone(Class, size_t idxIvars, void *z) +OBJC_EXPORT void +objc_setClassHandler(int (* _Nullable )(const char * _Nonnull)) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +objc_setMultithreaded(BOOL flag) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +class_createInstanceFromZone(Class _Nullable, size_t idxIvars, + void * _Nullable z) __OSX_DEPRECATED(10.0, 10.5, "use class_createInstance instead") - __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE + __IOS_UNAVAILABLE __TVOS_UNAVAILABLE + __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE OBJC_ARC_UNAVAILABLE; -OBJC_EXPORT void class_addMethods(Class, struct objc_method_list *) OBJC2_UNAVAILABLE; -OBJC_EXPORT void class_removeMethods(Class, struct objc_method_list *) OBJC2_UNAVAILABLE; -OBJC_EXPORT void _objc_resolve_categories_for_class(Class cls) OBJC2_UNAVAILABLE; +OBJC_EXPORT void +class_addMethods(Class _Nullable, struct objc_method_list * _Nonnull) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +class_removeMethods(Class _Nullable, struct objc_method_list * _Nonnull) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +_objc_resolve_categories_for_class(Class _Nonnull cls) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT Class _Nonnull +class_poseAs(Class _Nonnull imposter, Class _Nonnull original) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT unsigned int +method_getSizeOfArguments(Method _Nonnull m) + OBJC2_UNAVAILABLE; -OBJC_EXPORT Class class_poseAs(Class imposter, Class original) OBJC2_UNAVAILABLE; +OBJC_EXPORT unsigned +method_getArgumentInfo(struct objc_method * _Nonnull m, int arg, + const char * _Nullable * _Nonnull type, + int * _Nonnull offset) + OBJC2_UNAVAILABLE; -OBJC_EXPORT unsigned int method_getSizeOfArguments(Method m) OBJC2_UNAVAILABLE; -OBJC_EXPORT unsigned method_getArgumentInfo(struct objc_method *m, int arg, const char **type, int *offset) OBJC2_UNAVAILABLE; +OBJC_EXPORT Class _Nullable +objc_getOrigClass(const char * _Nonnull name) + OBJC2_UNAVAILABLE; -OBJC_EXPORT Class objc_getOrigClass(const char *name) OBJC2_UNAVAILABLE; #define OBJC_NEXT_METHOD_LIST 1 -OBJC_EXPORT struct objc_method_list *class_nextMethodList(Class, void **) OBJC2_UNAVAILABLE; +OBJC_EXPORT struct objc_method_list * _Nullable +class_nextMethodList(Class _Nullable, void * _Nullable * _Nullable) + OBJC2_UNAVAILABLE; // usage for nextMethodList // // void *iterator = 0; @@ -1791,13 +1977,36 @@ OBJC_EXPORT struct objc_method_list *class_nextMethodList(Class, void **) OBJC2_ // while ( mlist = class_nextMethodList( cls, &iterator ) ) // ; -OBJC_EXPORT id (*_alloc)(Class, size_t) OBJC2_UNAVAILABLE; -OBJC_EXPORT id (*_copy)(id, size_t) OBJC2_UNAVAILABLE; -OBJC_EXPORT id (*_realloc)(id, size_t) OBJC2_UNAVAILABLE; -OBJC_EXPORT id (*_dealloc)(id) OBJC2_UNAVAILABLE; -OBJC_EXPORT id (*_zoneAlloc)(Class, size_t, void *) OBJC2_UNAVAILABLE; -OBJC_EXPORT id (*_zoneRealloc)(id, size_t, void *) OBJC2_UNAVAILABLE; -OBJC_EXPORT id (*_zoneCopy)(id, size_t, void *) OBJC2_UNAVAILABLE; -OBJC_EXPORT void (*_error)(id, const char *, va_list) OBJC2_UNAVAILABLE; +OBJC_EXPORT id _Nullable +(* _Nonnull _alloc)(Class _Nullable, size_t) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _copy)(id _Nullable, size_t) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _realloc)(id _Nullable, size_t) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _dealloc)(id _Nullable) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _zoneAlloc)(Class _Nullable, size_t, void * _Nullable) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _zoneRealloc)(id _Nullable, size_t, void * _Nullable) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT id _Nullable +(* _Nonnull _zoneCopy)(id _Nullable, size_t, void * _Nullable) + OBJC2_UNAVAILABLE; + +OBJC_EXPORT void +(* _Nonnull _error)(id _Nullable, const char * _Nonnull, va_list) + OBJC2_UNAVAILABLE; #endif -- 2.45.2