objc-internal.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883
  1. /*
  2. * Copyright (c) 2009 Apple Inc. All Rights Reserved.
  3. *
  4. * @APPLE_LICENSE_HEADER_START@
  5. *
  6. * This file contains Original Code and/or Modifications of Original Code
  7. * as defined in and that are subject to the Apple Public Source License
  8. * Version 2.0 (the 'License'). You may not use this file except in
  9. * compliance with the License. Please obtain a copy of the License at
  10. * http://www.opensource.apple.com/apsl/ and read it before using this
  11. * file.
  12. *
  13. * The Original Code and all software distributed under the License are
  14. * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  15. * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  16. * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  18. * Please see the License for the specific language governing rights and
  19. * limitations under the License.
  20. *
  21. * @APPLE_LICENSE_HEADER_END@
  22. */
  23. #ifndef _OBJC_INTERNAL_H
  24. #define _OBJC_INTERNAL_H
  25. /*
  26. * WARNING DANGER HAZARD BEWARE EEK
  27. *
  28. * Everything in this file is for Apple Internal use only.
  29. * These will change in arbitrary OS updates and in unpredictable ways.
  30. * When your program breaks, you get to keep both pieces.
  31. */
  32. /*
  33. * objc-internal.h: Private SPI for use by other system frameworks.
  34. */
  35. #include <objc/objc.h>
  36. #include <objc/runtime.h>
  37. #include <Availability.h>
  38. #include <malloc/malloc.h>
  39. #include <mach-o/loader.h>
  40. #include <dispatch/dispatch.h>
  41. // Termination reasons in the OS_REASON_OBJC namespace.
  42. #define OBJC_EXIT_REASON_UNSPECIFIED 1
  43. #define OBJC_EXIT_REASON_GC_NOT_SUPPORTED 2
  44. // This is the allocation size required for each of the class and the metaclass
  45. // with objc_initializeClassPair() and objc_readClassPair().
  46. // The runtime's class structure will never grow beyond this.
  47. #define OBJC_MAX_CLASS_SIZE (32*sizeof(void*))
  48. __BEGIN_DECLS
  49. // In-place construction of an Objective-C class.
  50. // cls and metacls must each be OBJC_MAX_CLASS_SIZE bytes.
  51. // Returns nil if a class with the same name already exists.
  52. // Returns nil if the superclass is under construction.
  53. // Call objc_registerClassPair() when you are done.
  54. OBJC_EXPORT Class _Nullable
  55. objc_initializeClassPair(Class _Nullable superclass, const char * _Nonnull name,
  56. Class _Nonnull cls, Class _Nonnull metacls)
  57. OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0);
  58. // Class and metaclass construction from a compiler-generated memory image.
  59. // cls and cls->isa must each be OBJC_MAX_CLASS_SIZE bytes.
  60. // Extra bytes not used the the metadata must be zero.
  61. // info is the same objc_image_info that would be emitted by a static compiler.
  62. // Returns nil if a class with the same name already exists.
  63. // Returns nil if the superclass is nil and the class is not marked as a root.
  64. // Returns nil if the superclass is under construction.
  65. // Do not call objc_registerClassPair().
  66. #if __OBJC2__
  67. struct objc_image_info;
  68. OBJC_EXPORT Class _Nullable
  69. objc_readClassPair(Class _Nonnull cls,
  70. const struct objc_image_info * _Nonnull info)
  71. OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0, 2.0);
  72. #endif
  73. // Batch object allocation using malloc_zone_batch_malloc().
  74. OBJC_EXPORT unsigned
  75. class_createInstances(Class _Nullable cls, size_t extraBytes,
  76. id _Nonnull * _Nonnull results, unsigned num_requested)
  77. OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0)
  78. OBJC_ARC_UNAVAILABLE;
  79. // Get the isa pointer written into objects just before being freed.
  80. OBJC_EXPORT Class _Nonnull
  81. _objc_getFreedObjectClass(void)
  82. OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
  83. // env NSObjCMessageLoggingEnabled
  84. OBJC_EXPORT void
  85. instrumentObjcMessageSends(BOOL flag)
  86. OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
  87. // Initializer called by libSystem
  88. OBJC_EXPORT void
  89. _objc_init(void)
  90. #if __OBJC2__
  91. OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0);
  92. #else
  93. OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
  94. #endif
  95. // fork() safety called by libSystem
  96. OBJC_EXPORT void
  97. _objc_atfork_prepare(void)
  98. OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
  99. OBJC_EXPORT void
  100. _objc_atfork_parent(void)
  101. OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
  102. OBJC_EXPORT void
  103. _objc_atfork_child(void)
  104. OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
  105. // Return YES if GC is on and `object` is a GC allocation.
  106. OBJC_EXPORT BOOL
  107. objc_isAuto(id _Nullable object)
  108. __OSX_DEPRECATED(10.4, 10.8, "it always returns NO")
  109. __IOS_UNAVAILABLE __TVOS_UNAVAILABLE
  110. __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE;
  111. // GC debugging
  112. OBJC_EXPORT BOOL
  113. objc_dumpHeap(char * _Nonnull filename, unsigned long length)
  114. __OSX_DEPRECATED(10.4, 10.8, "it always returns NO")
  115. __IOS_UNAVAILABLE __TVOS_UNAVAILABLE
  116. __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE;
  117. // GC startup callback from Foundation
  118. OBJC_EXPORT malloc_zone_t * _Nullable
  119. objc_collect_init(int (* _Nonnull callback)(void))
  120. __OSX_DEPRECATED(10.4, 10.8, "it does nothing")
  121. __IOS_UNAVAILABLE __TVOS_UNAVAILABLE
  122. __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE;
  123. // Plainly-implemented GC barriers. Rosetta used to use these.
  124. OBJC_EXPORT id _Nullable
  125. objc_assign_strongCast_generic(id _Nullable value, id _Nullable * _Nonnull dest)
  126. UNAVAILABLE_ATTRIBUTE;
  127. OBJC_EXPORT id _Nullable
  128. objc_assign_global_generic(id _Nullable value, id _Nullable * _Nonnull dest)
  129. UNAVAILABLE_ATTRIBUTE;
  130. OBJC_EXPORT id _Nullable
  131. objc_assign_threadlocal_generic(id _Nullable value,
  132. id _Nullable * _Nonnull dest)
  133. UNAVAILABLE_ATTRIBUTE;
  134. OBJC_EXPORT id _Nullable
  135. objc_assign_ivar_generic(id _Nullable value, id _Nonnull dest, ptrdiff_t offset)
  136. UNAVAILABLE_ATTRIBUTE;
  137. // GC preflight for an app executable.
  138. // 1: some slice requires GC
  139. // 0: no slice requires GC
  140. // -1: I/O or file format error
  141. OBJC_EXPORT int
  142. objc_appRequiresGC(int fd)
  143. __OSX_AVAILABLE(10.11)
  144. __IOS_UNAVAILABLE __TVOS_UNAVAILABLE
  145. __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE;
  146. // Install missing-class callback. Used by the late unlamented ZeroLink.
  147. OBJC_EXPORT void
  148. _objc_setClassLoader(BOOL (* _Nonnull newClassLoader)(const char * _Nonnull))
  149. OBJC2_UNAVAILABLE;
  150. #if !(TARGET_OS_OSX && !TARGET_OS_IOSMAC && __i386__)
  151. OBJC_EXPORT void
  152. _objc_setClassCopyFixupHandler(void (* _Nonnull newFixupHandler)
  153. (Class _Nonnull oldClass, Class _Nonnull newClass));
  154. // fixme work around bug in Swift
  155. // OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0)
  156. #endif
  157. // Install handler for allocation failures.
  158. // Handler may abort, or throw, or provide an object to return.
  159. OBJC_EXPORT void
  160. _objc_setBadAllocHandler(id _Nullable (* _Nonnull newHandler)
  161. (Class _Nullable isa))
  162. OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0);
  163. // Used by ExceptionHandling.framework
  164. #if !__OBJC2__
  165. OBJC_EXPORT void
  166. _objc_error(id _Nullable rcv, const char * _Nonnull fmt, va_list args)
  167. __attribute__((noreturn))
  168. __OSX_DEPRECATED(10.0, 10.5, "use other logging facilities instead")
  169. __IOS_UNAVAILABLE __TVOS_UNAVAILABLE
  170. __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE;
  171. #endif
  172. /**
  173. * Returns the names of all the classes within a library.
  174. *
  175. * @param image The mach header for library or framework you are inquiring about.
  176. * @param outCount The number of class names returned.
  177. *
  178. * @return An array of C strings representing the class names.
  179. */
  180. OBJC_EXPORT const char * _Nonnull * _Nullable
  181. objc_copyClassNamesForImageHeader(const struct mach_header * _Nonnull mh,
  182. unsigned int * _Nullable outCount)
  183. OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
  184. // Tagged pointer objects.
  185. #if __LP64__
  186. #define OBJC_HAVE_TAGGED_POINTERS 1
  187. #endif
  188. #if OBJC_HAVE_TAGGED_POINTERS
  189. // Tagged pointer layout and usage is subject to change on different OS versions.
  190. // Tag indexes 0..<7 have a 60-bit payload.
  191. // Tag index 7 is reserved.
  192. // Tag indexes 8..<264 have a 52-bit payload.
  193. // Tag index 264 is reserved.
  194. #if __has_feature(objc_fixed_enum) || __cplusplus >= 201103L
  195. enum objc_tag_index_t : uint16_t
  196. #else
  197. typedef uint16_t objc_tag_index_t;
  198. enum
  199. #endif
  200. {
  201. // 60-bit payloads
  202. OBJC_TAG_NSAtom = 0,
  203. OBJC_TAG_1 = 1,
  204. OBJC_TAG_NSString = 2,
  205. OBJC_TAG_NSNumber = 3,
  206. OBJC_TAG_NSIndexPath = 4,
  207. OBJC_TAG_NSManagedObjectID = 5,
  208. OBJC_TAG_NSDate = 6,
  209. // 60-bit reserved
  210. OBJC_TAG_RESERVED_7 = 7,
  211. // 52-bit payloads
  212. OBJC_TAG_Photos_1 = 8,
  213. OBJC_TAG_Photos_2 = 9,
  214. OBJC_TAG_Photos_3 = 10,
  215. OBJC_TAG_Photos_4 = 11,
  216. OBJC_TAG_XPC_1 = 12,
  217. OBJC_TAG_XPC_2 = 13,
  218. OBJC_TAG_XPC_3 = 14,
  219. OBJC_TAG_XPC_4 = 15,
  220. OBJC_TAG_First60BitPayload = 0,
  221. OBJC_TAG_Last60BitPayload = 6,
  222. OBJC_TAG_First52BitPayload = 8,
  223. OBJC_TAG_Last52BitPayload = 263,
  224. OBJC_TAG_RESERVED_264 = 264
  225. };
  226. #if __has_feature(objc_fixed_enum) && !defined(__cplusplus)
  227. typedef enum objc_tag_index_t objc_tag_index_t;
  228. #endif
  229. // Returns true if tagged pointers are enabled.
  230. // The other functions below must not be called if tagged pointers are disabled.
  231. static inline bool
  232. _objc_taggedPointersEnabled(void);
  233. // Register a class for a tagged pointer tag.
  234. // Aborts if the tag is invalid or already in use.
  235. OBJC_EXPORT void
  236. _objc_registerTaggedPointerClass(objc_tag_index_t tag, Class _Nonnull cls)
  237. OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
  238. // Returns the registered class for the given tag.
  239. // Returns nil if the tag is valid but has no registered class.
  240. // Aborts if the tag is invalid.
  241. OBJC_EXPORT Class _Nullable
  242. _objc_getClassForTag(objc_tag_index_t tag)
  243. OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
  244. // Create a tagged pointer object with the given tag and payload.
  245. // Assumes the tag is valid.
  246. // Assumes tagged pointers are enabled.
  247. // The payload will be silently truncated to fit.
  248. static inline void * _Nonnull
  249. _objc_makeTaggedPointer(objc_tag_index_t tag, uintptr_t payload);
  250. // Return true if ptr is a tagged pointer object.
  251. // Does not check the validity of ptr's class.
  252. static inline bool
  253. _objc_isTaggedPointer(const void * _Nullable ptr);
  254. // Extract the tag value from the given tagged pointer object.
  255. // Assumes ptr is a valid tagged pointer object.
  256. // Does not check the validity of ptr's tag.
  257. static inline objc_tag_index_t
  258. _objc_getTaggedPointerTag(const void * _Nullable ptr);
  259. // Extract the payload from the given tagged pointer object.
  260. // Assumes ptr is a valid tagged pointer object.
  261. // The payload value is zero-extended.
  262. static inline uintptr_t
  263. _objc_getTaggedPointerValue(const void * _Nullable ptr);
  264. // Extract the payload from the given tagged pointer object.
  265. // Assumes ptr is a valid tagged pointer object.
  266. // The payload value is sign-extended.
  267. static inline intptr_t
  268. _objc_getTaggedPointerSignedValue(const void * _Nullable ptr);
  269. // Don't use the values below. Use the declarations above.
  270. #if (TARGET_OS_OSX || TARGET_OS_IOSMAC) && __x86_64__
  271. // 64-bit Mac - tag bit is LSB
  272. # define OBJC_MSB_TAGGED_POINTERS 0
  273. #else
  274. // Everything else - tag bit is MSB
  275. # define OBJC_MSB_TAGGED_POINTERS 1
  276. #endif
  277. #define _OBJC_TAG_INDEX_MASK 0x7
  278. // array slot includes the tag bit itself
  279. #define _OBJC_TAG_SLOT_COUNT 16
  280. #define _OBJC_TAG_SLOT_MASK 0xf
  281. #define _OBJC_TAG_EXT_INDEX_MASK 0xff
  282. // array slot has no extra bits
  283. #define _OBJC_TAG_EXT_SLOT_COUNT 256
  284. #define _OBJC_TAG_EXT_SLOT_MASK 0xff
  285. #if OBJC_MSB_TAGGED_POINTERS
  286. # define _OBJC_TAG_MASK (1UL<<63)
  287. # define _OBJC_TAG_INDEX_SHIFT 60
  288. # define _OBJC_TAG_SLOT_SHIFT 60
  289. # define _OBJC_TAG_PAYLOAD_LSHIFT 4
  290. # define _OBJC_TAG_PAYLOAD_RSHIFT 4
  291. # define _OBJC_TAG_EXT_MASK (0xfUL<<60)
  292. # define _OBJC_TAG_EXT_INDEX_SHIFT 52
  293. # define _OBJC_TAG_EXT_SLOT_SHIFT 52
  294. # define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 12
  295. # define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12
  296. #else
  297. # define _OBJC_TAG_MASK 1UL
  298. # define _OBJC_TAG_INDEX_SHIFT 1
  299. # define _OBJC_TAG_SLOT_SHIFT 0
  300. # define _OBJC_TAG_PAYLOAD_LSHIFT 0
  301. # define _OBJC_TAG_PAYLOAD_RSHIFT 4
  302. # define _OBJC_TAG_EXT_MASK 0xfUL
  303. # define _OBJC_TAG_EXT_INDEX_SHIFT 4
  304. # define _OBJC_TAG_EXT_SLOT_SHIFT 4
  305. # define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 0
  306. # define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12
  307. #endif
  308. extern uintptr_t objc_debug_taggedpointer_obfuscator;
  309. static inline void * _Nonnull
  310. _objc_encodeTaggedPointer(uintptr_t ptr)
  311. {
  312. return (void *)(objc_debug_taggedpointer_obfuscator ^ ptr);
  313. }
  314. static inline uintptr_t
  315. _objc_decodeTaggedPointer(const void * _Nullable ptr)
  316. {
  317. return (uintptr_t)ptr ^ objc_debug_taggedpointer_obfuscator;
  318. }
  319. static inline bool
  320. _objc_taggedPointersEnabled(void)
  321. {
  322. extern uintptr_t objc_debug_taggedpointer_mask;
  323. return (objc_debug_taggedpointer_mask != 0);
  324. }
  325. static inline void * _Nonnull
  326. _objc_makeTaggedPointer(objc_tag_index_t tag, uintptr_t value)
  327. {
  328. // PAYLOAD_LSHIFT and PAYLOAD_RSHIFT are the payload extraction shifts.
  329. // They are reversed here for payload insertion.
  330. // assert(_objc_taggedPointersEnabled());
  331. if (tag <= OBJC_TAG_Last60BitPayload) {
  332. // assert(((value << _OBJC_TAG_PAYLOAD_RSHIFT) >> _OBJC_TAG_PAYLOAD_LSHIFT) == value);
  333. uintptr_t result =
  334. (_OBJC_TAG_MASK |
  335. ((uintptr_t)tag << _OBJC_TAG_INDEX_SHIFT) |
  336. ((value << _OBJC_TAG_PAYLOAD_RSHIFT) >> _OBJC_TAG_PAYLOAD_LSHIFT));
  337. return _objc_encodeTaggedPointer(result);
  338. } else {
  339. // assert(tag >= OBJC_TAG_First52BitPayload);
  340. // assert(tag <= OBJC_TAG_Last52BitPayload);
  341. // assert(((value << _OBJC_TAG_EXT_PAYLOAD_RSHIFT) >> _OBJC_TAG_EXT_PAYLOAD_LSHIFT) == value);
  342. uintptr_t result =
  343. (_OBJC_TAG_EXT_MASK |
  344. ((uintptr_t)(tag - OBJC_TAG_First52BitPayload) << _OBJC_TAG_EXT_INDEX_SHIFT) |
  345. ((value << _OBJC_TAG_EXT_PAYLOAD_RSHIFT) >> _OBJC_TAG_EXT_PAYLOAD_LSHIFT));
  346. return _objc_encodeTaggedPointer(result);
  347. }
  348. }
  349. static inline bool
  350. _objc_isTaggedPointer(const void * _Nullable ptr)
  351. {
  352. return ((uintptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
  353. }
  354. static inline objc_tag_index_t
  355. _objc_getTaggedPointerTag(const void * _Nullable ptr)
  356. {
  357. // assert(_objc_isTaggedPointer(ptr));
  358. uintptr_t value = _objc_decodeTaggedPointer(ptr);
  359. uintptr_t basicTag = (value >> _OBJC_TAG_INDEX_SHIFT) & _OBJC_TAG_INDEX_MASK;
  360. uintptr_t extTag = (value >> _OBJC_TAG_EXT_INDEX_SHIFT) & _OBJC_TAG_EXT_INDEX_MASK;
  361. if (basicTag == _OBJC_TAG_INDEX_MASK) {
  362. return (objc_tag_index_t)(extTag + OBJC_TAG_First52BitPayload);
  363. } else {
  364. return (objc_tag_index_t)basicTag;
  365. }
  366. }
  367. static inline uintptr_t
  368. _objc_getTaggedPointerValue(const void * _Nullable ptr)
  369. {
  370. // assert(_objc_isTaggedPointer(ptr));
  371. uintptr_t value = _objc_decodeTaggedPointer(ptr);
  372. uintptr_t basicTag = (value >> _OBJC_TAG_INDEX_SHIFT) & _OBJC_TAG_INDEX_MASK;
  373. if (basicTag == _OBJC_TAG_INDEX_MASK) {
  374. return (value << _OBJC_TAG_EXT_PAYLOAD_LSHIFT) >> _OBJC_TAG_EXT_PAYLOAD_RSHIFT;
  375. } else {
  376. return (value << _OBJC_TAG_PAYLOAD_LSHIFT) >> _OBJC_TAG_PAYLOAD_RSHIFT;
  377. }
  378. }
  379. static inline intptr_t
  380. _objc_getTaggedPointerSignedValue(const void * _Nullable ptr)
  381. {
  382. // assert(_objc_isTaggedPointer(ptr));
  383. uintptr_t value = _objc_decodeTaggedPointer(ptr);
  384. uintptr_t basicTag = (value >> _OBJC_TAG_INDEX_SHIFT) & _OBJC_TAG_INDEX_MASK;
  385. if (basicTag == _OBJC_TAG_INDEX_MASK) {
  386. return ((intptr_t)value << _OBJC_TAG_EXT_PAYLOAD_LSHIFT) >> _OBJC_TAG_EXT_PAYLOAD_RSHIFT;
  387. } else {
  388. return ((intptr_t)value << _OBJC_TAG_PAYLOAD_LSHIFT) >> _OBJC_TAG_PAYLOAD_RSHIFT;
  389. }
  390. }
  391. // OBJC_HAVE_TAGGED_POINTERS
  392. #endif
  393. /**
  394. * Returns the method implementation of an object.
  395. *
  396. * @param obj An Objective-C object.
  397. * @param name An Objective-C selector.
  398. *
  399. * @return The IMP corresponding to the instance method implemented by
  400. * the class of \e obj.
  401. *
  402. * @note Equivalent to:
  403. *
  404. * class_getMethodImplementation(object_getClass(obj), name);
  405. */
  406. OBJC_EXPORT IMP _Nonnull
  407. object_getMethodImplementation(id _Nullable obj, SEL _Nonnull name)
  408. OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
  409. OBJC_EXPORT IMP _Nonnull
  410. object_getMethodImplementation_stret(id _Nullable obj, SEL _Nonnull name)
  411. OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0)
  412. OBJC_ARM64_UNAVAILABLE;
  413. /**
  414. * Adds multiple methods to a class in bulk. This amortizes overhead that can be
  415. * expensive when adding methods one by one with class_addMethod.
  416. *
  417. * @param cls The class to which to add the methods.
  418. * @param names An array of selectors for the methods to add.
  419. * @param imps An array of functions which implement the new methods.
  420. * @param types An array of strings that describe the types of each method's
  421. * arguments.
  422. * @param count The number of items in the names, imps, and types arrays.
  423. * @param outFiledCount Upon return, contains the number of failed selectors in
  424. * the returned array.
  425. *
  426. * @return A NULL-terminated C array of selectors which could not be added. A
  427. * method cannot be added when a method of that name already exists on that
  428. * class. When no failures occur, the return value is \c NULL. When a non-NULL
  429. * value is returned, the caller must free the array with \c free().
  430. *
  431. */
  432. #if __OBJC2__
  433. OBJC_EXPORT _Nullable SEL * _Nullable
  434. class_addMethodsBulk(_Nullable Class cls, _Nonnull const SEL * _Nonnull names,
  435. _Nonnull const IMP * _Nonnull imps,
  436. const char * _Nonnull * _Nonnull types, uint32_t count,
  437. uint32_t * _Nullable outFailedCount)
  438. OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
  439. #endif
  440. /**
  441. * Replaces multiple methods in a class in bulk. This amortizes overhead that
  442. * can be expensive when adding methods one by one with class_replaceMethod.
  443. *
  444. * @param cls The class to modify.
  445. * @param names An array of selectors for the methods to replace.
  446. * @param imps An array of functions will be the new method implementantations.
  447. * @param types An array of strings that describe the types of each method's
  448. * arguments.
  449. * @param count The number of items in the names, imps, and types arrays.
  450. */
  451. #if __OBJC2__
  452. OBJC_EXPORT void
  453. class_replaceMethodsBulk(_Nullable Class cls,
  454. _Nonnull const SEL * _Nonnull names,
  455. _Nonnull const IMP * _Nonnull imps,
  456. const char * _Nonnull * _Nonnull types,
  457. uint32_t count)
  458. OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
  459. #endif
  460. // Instance-specific instance variable layout. This is no longer implemented.
  461. OBJC_EXPORT void
  462. _class_setIvarLayoutAccessor(Class _Nullable cls,
  463. const uint8_t* _Nullable (* _Nonnull accessor)
  464. (id _Nullable object))
  465. UNAVAILABLE_ATTRIBUTE;
  466. OBJC_EXPORT const uint8_t * _Nullable
  467. _object_getIvarLayout(Class _Nullable cls, id _Nullable object)
  468. UNAVAILABLE_ATTRIBUTE;
  469. /*
  470. "Unknown" includes non-object ivars and non-ARC non-__weak ivars
  471. "Strong" includes ARC __strong ivars
  472. "Weak" includes ARC and new MRC __weak ivars
  473. "Unretained" includes ARC __unsafe_unretained and old GC+MRC __weak ivars
  474. */
  475. typedef enum {
  476. objc_ivar_memoryUnknown, // unknown / unknown
  477. objc_ivar_memoryStrong, // direct access / objc_storeStrong
  478. objc_ivar_memoryWeak, // objc_loadWeak[Retained] / objc_storeWeak
  479. objc_ivar_memoryUnretained // direct access / direct access
  480. } objc_ivar_memory_management_t;
  481. OBJC_EXPORT objc_ivar_memory_management_t
  482. _class_getIvarMemoryManagement(Class _Nullable cls, Ivar _Nonnull ivar)
  483. OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
  484. OBJC_EXPORT BOOL _class_isFutureClass(Class _Nullable cls)
  485. OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
  486. // API to only be called by root classes like NSObject or NSProxy
  487. OBJC_EXPORT
  488. id _Nonnull
  489. _objc_rootRetain(id _Nonnull obj)
  490. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  491. OBJC_EXPORT
  492. void
  493. _objc_rootRelease(id _Nonnull obj)
  494. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  495. OBJC_EXPORT
  496. bool
  497. _objc_rootReleaseWasZero(id _Nonnull obj)
  498. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  499. OBJC_EXPORT
  500. bool
  501. _objc_rootTryRetain(id _Nonnull obj)
  502. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  503. OBJC_EXPORT
  504. bool
  505. _objc_rootIsDeallocating(id _Nonnull obj)
  506. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  507. OBJC_EXPORT
  508. id _Nonnull
  509. _objc_rootAutorelease(id _Nonnull obj)
  510. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  511. OBJC_EXPORT
  512. uintptr_t
  513. _objc_rootRetainCount(id _Nonnull obj)
  514. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  515. OBJC_EXPORT
  516. id _Nonnull
  517. _objc_rootInit(id _Nonnull obj)
  518. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  519. OBJC_EXPORT
  520. id _Nullable
  521. _objc_rootAllocWithZone(Class _Nonnull cls, malloc_zone_t * _Nullable zone)
  522. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  523. OBJC_EXPORT
  524. id _Nullable
  525. _objc_rootAlloc(Class _Nonnull cls)
  526. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  527. OBJC_EXPORT
  528. void
  529. _objc_rootDealloc(id _Nonnull obj)
  530. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  531. OBJC_EXPORT
  532. void
  533. _objc_rootFinalize(id _Nonnull obj)
  534. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  535. OBJC_EXPORT
  536. malloc_zone_t * _Nonnull
  537. _objc_rootZone(id _Nonnull obj)
  538. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  539. OBJC_EXPORT
  540. uintptr_t
  541. _objc_rootHash(id _Nonnull obj)
  542. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  543. OBJC_EXPORT
  544. void * _Nonnull
  545. objc_autoreleasePoolPush(void)
  546. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  547. OBJC_EXPORT
  548. void
  549. objc_autoreleasePoolPop(void * _Nonnull context)
  550. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  551. OBJC_EXPORT id _Nullable
  552. objc_alloc(Class _Nullable cls)
  553. OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
  554. OBJC_EXPORT id _Nullable
  555. objc_allocWithZone(Class _Nullable cls)
  556. OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
  557. OBJC_EXPORT id _Nullable
  558. objc_retain(id _Nullable obj)
  559. __asm__("_objc_retain")
  560. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  561. OBJC_EXPORT void
  562. objc_release(id _Nullable obj)
  563. __asm__("_objc_release")
  564. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  565. OBJC_EXPORT id _Nullable
  566. objc_autorelease(id _Nullable obj)
  567. __asm__("_objc_autorelease")
  568. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  569. // Prepare a value at +1 for return through a +0 autoreleasing convention.
  570. OBJC_EXPORT id _Nullable
  571. objc_autoreleaseReturnValue(id _Nullable obj)
  572. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  573. // Prepare a value at +0 for return through a +0 autoreleasing convention.
  574. OBJC_EXPORT id _Nullable
  575. objc_retainAutoreleaseReturnValue(id _Nullable obj)
  576. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  577. // Accept a value returned through a +0 autoreleasing convention for use at +1.
  578. OBJC_EXPORT id _Nullable
  579. objc_retainAutoreleasedReturnValue(id _Nullable obj)
  580. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  581. // Accept a value returned through a +0 autoreleasing convention for use at +0.
  582. OBJC_EXPORT id _Nullable
  583. objc_unsafeClaimAutoreleasedReturnValue(id _Nullable obj)
  584. OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0);
  585. OBJC_EXPORT void
  586. objc_storeStrong(id _Nullable * _Nonnull location, id _Nullable obj)
  587. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  588. OBJC_EXPORT id _Nullable
  589. objc_retainAutorelease(id _Nullable obj)
  590. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  591. // obsolete.
  592. OBJC_EXPORT id _Nullable
  593. objc_retain_autorelease(id _Nullable obj)
  594. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  595. OBJC_EXPORT id _Nullable
  596. objc_loadWeakRetained(id _Nullable * _Nonnull location)
  597. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  598. OBJC_EXPORT id _Nullable
  599. objc_initWeak(id _Nullable * _Nonnull location, id _Nullable val)
  600. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  601. // Like objc_storeWeak, but stores nil if the new object is deallocating
  602. // or the new object's class does not support weak references.
  603. // Returns the value stored (either the new object or nil).
  604. OBJC_EXPORT id _Nullable
  605. objc_storeWeakOrNil(id _Nullable * _Nonnull location, id _Nullable obj)
  606. OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0);
  607. // Like objc_initWeak, but stores nil if the new object is deallocating
  608. // or the new object's class does not support weak references.
  609. // Returns the value stored (either the new object or nil).
  610. OBJC_EXPORT id _Nullable
  611. objc_initWeakOrNil(id _Nullable * _Nonnull location, id _Nullable val)
  612. OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0);
  613. OBJC_EXPORT void
  614. objc_destroyWeak(id _Nullable * _Nonnull location)
  615. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  616. OBJC_EXPORT void
  617. objc_copyWeak(id _Nullable * _Nonnull to, id _Nullable * _Nonnull from)
  618. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  619. OBJC_EXPORT void
  620. objc_moveWeak(id _Nullable * _Nonnull to, id _Nullable * _Nonnull from)
  621. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  622. OBJC_EXPORT void
  623. _objc_autoreleasePoolPrint(void)
  624. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  625. OBJC_EXPORT BOOL
  626. objc_should_deallocate(id _Nonnull object)
  627. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  628. OBJC_EXPORT void
  629. objc_clear_deallocating(id _Nonnull object)
  630. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  631. // to make CF link for now
  632. OBJC_EXPORT void * _Nonnull
  633. _objc_autoreleasePoolPush(void)
  634. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  635. OBJC_EXPORT void
  636. _objc_autoreleasePoolPop(void * _Nonnull context)
  637. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  638. // Extra @encode data for XPC, or NULL
  639. OBJC_EXPORT const char * _Nullable
  640. _protocol_getMethodTypeEncoding(Protocol * _Nonnull proto, SEL _Nonnull sel,
  641. BOOL isRequiredMethod, BOOL isInstanceMethod)
  642. OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0);
  643. // API to only be called by classes that provide their own reference count storage
  644. OBJC_EXPORT void
  645. _objc_deallocOnMainThreadHelper(void * _Nullable context)
  646. OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
  647. // On async versus sync deallocation and the _dealloc2main flag
  648. //
  649. // Theory:
  650. //
  651. // If order matters, then code must always: [self dealloc].
  652. // If order doesn't matter, then always async should be safe.
  653. //
  654. // Practice:
  655. //
  656. // The _dealloc2main bit is set for GUI objects that may be retained by other
  657. // threads. Once deallocation begins on the main thread, doing more async
  658. // deallocation will at best cause extra UI latency and at worst cause
  659. // use-after-free bugs in unretained delegate style patterns. Yes, this is
  660. // extremely fragile. Yes, in the long run, developers should switch to weak
  661. // references.
  662. //
  663. // Note is NOT safe to do any equality check against the result of
  664. // dispatch_get_current_queue(). The main thread can and does drain more than
  665. // one dispatch queue. That is why we call pthread_main_np().
  666. //
  667. typedef enum {
  668. _OBJC_RESURRECT_OBJECT = -1, /* _logicBlock has called -retain, and scheduled a -release for later. */
  669. _OBJC_DEALLOC_OBJECT_NOW = 1, /* call [self dealloc] immediately. */
  670. _OBJC_DEALLOC_OBJECT_LATER = 2 /* call [self dealloc] on the main queue. */
  671. } _objc_object_disposition_t;
  672. #define _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC_BLOCK(_rc_ivar, _logicBlock) \
  673. -(id)retain { \
  674. /* this will fail to compile if _rc_ivar is an unsigned type */ \
  675. int _retain_count_ivar_must_not_be_unsigned[0L - (__typeof__(_rc_ivar))-1] __attribute__((unused)); \
  676. __typeof__(_rc_ivar) _prev = __sync_fetch_and_add(&_rc_ivar, 2); \
  677. if (_prev < -2) { /* specifically allow resurrection from logical 0. */ \
  678. __builtin_trap(); /* BUG: retain of over-released ref */ \
  679. } \
  680. return self; \
  681. } \
  682. -(oneway void)release { \
  683. __typeof__(_rc_ivar) _prev = __sync_fetch_and_sub(&_rc_ivar, 2); \
  684. if (_prev > 0) { \
  685. return; \
  686. } else if (_prev < 0) { \
  687. __builtin_trap(); /* BUG: over-release */ \
  688. } \
  689. _objc_object_disposition_t fate = _logicBlock(self); \
  690. if (fate == _OBJC_RESURRECT_OBJECT) { \
  691. return; \
  692. } \
  693. /* mark the object as deallocating. */ \
  694. if (!__sync_bool_compare_and_swap(&_rc_ivar, -2, 1)) { \
  695. __builtin_trap(); /* BUG: dangling ref did a retain */ \
  696. } \
  697. if (fate == _OBJC_DEALLOC_OBJECT_NOW) { \
  698. [self dealloc]; \
  699. } else if (fate == _OBJC_DEALLOC_OBJECT_LATER) { \
  700. dispatch_barrier_async_f(dispatch_get_main_queue(), self, \
  701. _objc_deallocOnMainThreadHelper); \
  702. } else { \
  703. __builtin_trap(); /* BUG: bogus fate value */ \
  704. } \
  705. } \
  706. -(NSUInteger)retainCount { \
  707. return (_rc_ivar + 2) >> 1; \
  708. } \
  709. -(BOOL)_tryRetain { \
  710. __typeof__(_rc_ivar) _prev; \
  711. do { \
  712. _prev = _rc_ivar; \
  713. if (_prev & 1) { \
  714. return 0; \
  715. } else if (_prev == -2) { \
  716. return 0; \
  717. } else if (_prev < -2) { \
  718. __builtin_trap(); /* BUG: over-release elsewhere */ \
  719. } \
  720. } while ( ! __sync_bool_compare_and_swap(&_rc_ivar, _prev, _prev + 2)); \
  721. return 1; \
  722. } \
  723. -(BOOL)_isDeallocating { \
  724. if (_rc_ivar == -2) { \
  725. return 1; \
  726. } else if (_rc_ivar < -2) { \
  727. __builtin_trap(); /* BUG: over-release elsewhere */ \
  728. } \
  729. return _rc_ivar & 1; \
  730. }
  731. #define _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, _dealloc2main) \
  732. _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC_BLOCK(_rc_ivar, (^(id _self_ __attribute__((unused))) { \
  733. if (_dealloc2main && !pthread_main_np()) { \
  734. return _OBJC_DEALLOC_OBJECT_LATER; \
  735. } else { \
  736. return _OBJC_DEALLOC_OBJECT_NOW; \
  737. } \
  738. }))
  739. #define _OBJC_SUPPORTED_INLINE_REFCNT(_rc_ivar) _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, 0)
  740. #define _OBJC_SUPPORTED_INLINE_REFCNT_WITH_DEALLOC2MAIN(_rc_ivar) _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, 1)
  741. __END_DECLS
  742. #endif