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