objc-internal.h 35 KB

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