]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-private.h
objc4-551.1.tar.gz
[apple/objc4.git] / runtime / objc-private.h
1 /*
2 * Copyright (c) 1999-2007 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 * objc-private.h
25 * Copyright 1988-1996, NeXT Software, Inc.
26 */
27
28 #ifndef _OBJC_PRIVATE_H_
29 #define _OBJC_PRIVATE_H_
30
31 #include "objc-config.h"
32
33 /* Isolate ourselves from the definitions of id and Class in the compiler
34 * and public headers.
35 */
36
37 #ifdef _OBJC_OBJC_H_
38 #error include objc-private.h before other headers
39 #endif
40
41 #define OBJC_TYPES_DEFINED 1
42 #define OBJC_OLD_DISPATCH_PROTOTYPES 0
43
44 #include <cstddef> // for nullptr_t
45 #include <stdint.h>
46 #include <assert.h>
47
48 struct objc_class;
49 struct objc_object;
50
51 typedef struct objc_class *Class;
52 typedef struct objc_object *id;
53
54 #if SUPPORT_TAGGED_POINTERS
55
56 #define TAG_COUNT 8
57 #define TAG_MASK 1
58 #define TAG_SLOT_SHIFT 0
59 #define TAG_SLOT_MASK 0xf
60 #define TAG_PAYLOAD_LSHIFT 0
61 #define TAG_PAYLOAD_RSHIFT 4
62
63 extern "C" { extern Class objc_debug_taggedpointer_classes[TAG_COUNT*2]; }
64 #define objc_tag_classes objc_debug_taggedpointer_classes
65
66 #endif
67
68
69 struct objc_object {
70 private:
71 uintptr_t isa;
72
73 public:
74
75 // ISA() assumes this is NOT a tagged pointer object
76 Class ISA()
77 {
78 assert(!isTaggedPointer());
79 return (Class)isa;
80 }
81
82 // getIsa() allows this to be a tagged pointer object
83 Class getIsa()
84 {
85 #if SUPPORT_TAGGED_POINTERS
86 if (isTaggedPointer()) {
87 uintptr_t slot =
88 ((uintptr_t)this >> TAG_SLOT_SHIFT) & TAG_SLOT_MASK;
89 return objc_tag_classes[slot];
90 }
91 #endif
92 return ISA();
93 }
94
95 // changeIsa() should be used to change the isa of existing objects.
96 // If this is a new object, use initIsa() for performance.
97 Class changeIsa(Class cls);
98
99 // initIsa() should be used to init the isa of new objects only.
100 // If this object already has an isa, use changeIsa() for correctness.
101 void initIsa(Class cls)
102 {
103 assert(!isTaggedPointer());
104 isa = (uintptr_t)cls;
105 }
106
107 bool isTaggedPointer()
108 {
109 #if SUPPORT_TAGGED_POINTERS
110 return ((uintptr_t)this & TAG_MASK);
111 #else
112 return false;
113 #endif
114 }
115 };
116
117 #if __OBJC2__
118 typedef struct method_t *Method;
119 typedef struct ivar_t *Ivar;
120 typedef struct category_t *Category;
121 typedef struct property_t *objc_property_t;
122 #else
123 typedef struct old_method *Method;
124 typedef struct old_ivar *Ivar;
125 typedef struct old_category *Category;
126 typedef struct old_property *objc_property_t;
127 #endif
128
129 #include "objc.h"
130 #include "runtime.h"
131 #include "objc-os.h"
132
133 #if __OBJC2__
134 #include "objc-runtime-new.h"
135 #else
136 #include "objc-runtime-old.h"
137 #endif
138
139 #include "maptable.h"
140 #include "hashtable2.h"
141 #include "objc-api.h"
142 #include "objc-config.h"
143 #include "objc-references.h"
144 #include "objc-initialize.h"
145 #include "objc-loadmethod.h"
146 #include "objc-internal.h"
147 #include "objc-abi.h"
148
149 #include "objc-auto.h"
150
151 #define __APPLE_API_PRIVATE
152 #include "objc-gdb.h"
153 #undef __APPLE_API_PRIVATE
154
155 /* Do not include message.h here. */
156 /* #include "message.h" */
157
158
159 __BEGIN_DECLS
160
161 inline Class objc_object::changeIsa(Class cls)
162 {
163 assert(!isTaggedPointer());
164
165 Class old;
166 do {
167 old = (Class)isa;
168 } while (!OSAtomicCompareAndSwapPtr(old, cls, (void**)&isa));
169
170 if (old && old->instancesHaveAssociatedObjects()) {
171 cls->setInstancesHaveAssociatedObjects();
172 }
173
174 return old;
175 }
176
177
178 #if (defined(OBJC_NO_GC) && SUPPORT_GC) || \
179 (!defined(OBJC_NO_GC) && !SUPPORT_GC)
180 # error OBJC_NO_GC and SUPPORT_GC inconsistent
181 #endif
182
183 #if SUPPORT_GC
184 # include <auto_zone.h>
185 // PRIVATE_EXTERN is needed to help the compiler know "how" extern these are
186 PRIVATE_EXTERN extern int8_t UseGC; // equivalent to calling objc_collecting_enabled()
187 PRIVATE_EXTERN extern auto_zone_t *gc_zone; // the GC zone, or NULL if no GC
188 extern void objc_addRegisteredClass(Class c);
189 extern void objc_removeRegisteredClass(Class c);
190 #else
191 # define UseGC NO
192 # define gc_zone NULL
193 # define objc_addRegisteredClass(c) do {} while(0)
194 # define objc_removeRegisteredClass(c) do {} while(0)
195 /* Uses of the following must be protected with UseGC. */
196 extern id gc_unsupported_dont_call();
197 # define auto_zone_allocate_object gc_unsupported_dont_call
198 # define auto_zone_retain gc_unsupported_dont_call
199 # define auto_zone_release gc_unsupported_dont_call
200 # define auto_zone_is_valid_pointer gc_unsupported_dont_call
201 # define auto_zone_write_barrier_memmove gc_unsupported_dont_call
202 # define AUTO_OBJECT_SCANNED 0
203 #endif
204
205
206 typedef struct {
207 uint32_t version; // currently 0
208 uint32_t flags;
209 } objc_image_info;
210
211 // masks for objc_image_info.flags
212 #define OBJC_IMAGE_IS_REPLACEMENT (1<<0)
213 #define OBJC_IMAGE_SUPPORTS_GC (1<<1)
214 #define OBJC_IMAGE_REQUIRES_GC (1<<2)
215 #define OBJC_IMAGE_OPTIMIZED_BY_DYLD (1<<3)
216 #define OBJC_IMAGE_SUPPORTS_COMPACTION (1<<4) // might be re-assignable
217
218
219 #define _objcHeaderIsReplacement(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_IS_REPLACEMENT))
220
221 /* OBJC_IMAGE_IS_REPLACEMENT:
222 Don't load any classes
223 Don't load any categories
224 Do fix up selector refs (@selector points to them)
225 Do fix up class refs (@class and objc_msgSend points to them)
226 Do fix up protocols (@protocol points to them)
227 Do fix up superclass pointers in classes ([super ...] points to them)
228 Future: do load new classes?
229 Future: do load new categories?
230 Future: do insert new methods on existing classes?
231 Future: do insert new methods on existing categories?
232 */
233
234 #define _objcInfoSupportsGC(info) (((info)->flags & OBJC_IMAGE_SUPPORTS_GC) ? 1 : 0)
235 #define _objcInfoRequiresGC(info) (((info)->flags & OBJC_IMAGE_REQUIRES_GC) ? 1 : 0)
236 #define _objcHeaderSupportsGC(h) ((h)->info && _objcInfoSupportsGC((h)->info))
237 #define _objcHeaderRequiresGC(h) ((h)->info && _objcInfoRequiresGC((h)->info))
238
239 /* OBJC_IMAGE_SUPPORTS_GC:
240 was compiled with -fobjc-gc flag, regardless of whether write-barriers were issued
241 if executable image compiled this way, then all subsequent libraries etc. must also be this way
242 */
243
244 #define _objcHeaderOptimizedByDyld(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_OPTIMIZED_BY_DYLD))
245
246 /* OBJC_IMAGE_OPTIMIZED_BY_DYLD:
247 Assorted metadata precooked in the dyld shared cache.
248 Never set for images outside the shared cache file itself.
249 */
250
251
252 typedef struct _header_info {
253 struct _header_info *next;
254 const headerType *mhdr;
255 const objc_image_info *info;
256 const char *fname; // same as Dl_info.dli_fname
257 bool loaded;
258 bool inSharedCache;
259 bool allClassesRealized;
260
261 // Do not add fields without editing ObjCModernAbstraction.hpp
262
263 #if !__OBJC2__
264 struct old_protocol **proto_refs;
265 struct objc_module *mod_ptr;
266 size_t mod_count;
267 # if TARGET_OS_WIN32
268 struct objc_module **modules;
269 size_t moduleCount;
270 struct old_protocol **protocols;
271 size_t protocolCount;
272 void *imageinfo;
273 size_t imageinfoBytes;
274 SEL *selrefs;
275 size_t selrefCount;
276 struct objc_class **clsrefs;
277 size_t clsrefCount;
278 TCHAR *moduleName;
279 # endif
280 #endif
281 } header_info;
282
283 extern header_info *FirstHeader;
284 extern header_info *LastHeader;
285 extern int HeaderCount;
286
287 extern void appendHeader(header_info *hi);
288 extern void removeHeader(header_info *hi);
289
290 extern objc_image_info *_getObjcImageInfo(const headerType *head, size_t *size);
291 extern BOOL _hasObjcContents(const header_info *hi);
292
293
294 /* selectors */
295 extern void sel_init(BOOL gc, size_t selrefCount);
296 extern SEL sel_registerNameNoLock(const char *str, BOOL copy);
297 extern void sel_lock(void);
298 extern void sel_unlock(void);
299 extern BOOL sel_preoptimizationValid(const header_info *hi);
300 extern void sel_nuke_nolock(void);
301
302 extern SEL SEL_load;
303 extern SEL SEL_initialize;
304 extern SEL SEL_resolveClassMethod;
305 extern SEL SEL_resolveInstanceMethod;
306 extern SEL SEL_cxx_construct;
307 extern SEL SEL_cxx_destruct;
308 extern SEL SEL_retain;
309 extern SEL SEL_release;
310 extern SEL SEL_autorelease;
311 extern SEL SEL_retainCount;
312 extern SEL SEL_alloc;
313 extern SEL SEL_allocWithZone;
314 extern SEL SEL_copy;
315 extern SEL SEL_new;
316 extern SEL SEL_finalize;
317 extern SEL SEL_forwardInvocation;
318
319 /* preoptimization */
320 extern void preopt_init(void);
321 extern void disableSharedCacheOptimizations(void);
322 extern bool isPreoptimized(void);
323 extern header_info *preoptimizedHinfoForHeader(const headerType *mhdr);
324
325 #if __cplusplus
326 namespace objc_opt { struct objc_selopt_t; };
327 extern const struct objc_opt::objc_selopt_t *preoptimizedSelectors(void);
328 extern Class getPreoptimizedClass(const char *name);
329 #endif
330
331
332
333 /* optional malloc zone for runtime data */
334 extern malloc_zone_t *_objc_internal_zone(void);
335 extern void *_malloc_internal(size_t size);
336 extern void *_calloc_internal(size_t count, size_t size);
337 extern void *_realloc_internal(void *ptr, size_t size);
338 extern char *_strdup_internal(const char *str);
339 extern char *_strdupcat_internal(const char *s1, const char *s2);
340 extern uint8_t *_ustrdup_internal(const uint8_t *str);
341 extern void *_memdup_internal(const void *mem, size_t size);
342 extern void _free_internal(void *ptr);
343 extern size_t _malloc_size_internal(void *ptr);
344
345 extern Class _calloc_class(size_t size);
346
347 /* method lookup */
348 extern IMP lookUpImpOrNil(Class, SEL, id obj, bool initialize, bool cache, bool resolver);
349 extern IMP lookUpImpOrForward(Class, SEL, id obj, bool initialize, bool cache, bool resolver);
350
351 extern IMP lookupMethodInClassAndLoadCache(Class cls, SEL sel);
352
353 extern bool objcMsgLogEnabled;
354 extern bool logMessageSend(bool isClassMethod,
355 const char *objectsClass,
356 const char *implementingClass,
357 SEL selector);
358
359 /* message dispatcher */
360 extern IMP _class_lookupMethodAndLoadCache3(id, SEL, Class);
361
362 #if !OBJC_OLD_DISPATCH_PROTOTYPES
363 extern void _objc_msgForward_impcache(void);
364 extern void _objc_ignored_method(void);
365 extern void _objc_msgSend_uncached_impcache(void);
366 #else
367 extern id _objc_msgForward_impcache(id, SEL, ...);
368 extern id _objc_ignored_method(id, SEL, ...);
369 extern id _objc_msgSend_uncached_impcache(id, SEL, ...);
370 #endif
371
372 /* errors */
373 extern void __objc_error(id, const char *, ...) __attribute__((format (printf, 2, 3), noreturn));
374 extern void _objc_inform(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
375 extern void _objc_inform_on_crash(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
376 extern void _objc_inform_now_and_on_crash(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
377 extern void _objc_inform_deprecated(const char *oldname, const char *newname) __attribute__((noinline));
378 extern void inform_duplicate(const char *name, Class oldCls, Class cls);
379 extern bool crashlog_header_name(header_info *hi);
380 extern bool crashlog_header_name_string(const char *name);
381
382 /* magic */
383 extern Class _objc_getFreedObjectClass (void);
384
385 /* map table additions */
386 extern void *NXMapKeyCopyingInsert(NXMapTable *table, const void *key, const void *value);
387 extern void *NXMapKeyFreeingRemove(NXMapTable *table, const void *key);
388
389 /* hash table additions */
390 extern unsigned _NXHashCapacity(NXHashTable *table);
391 extern void _NXHashRehashToCapacity(NXHashTable *table, unsigned newCapacity);
392
393 /* property attribute parsing */
394 extern const char *copyPropertyAttributeString(const objc_property_attribute_t *attrs, unsigned int count);
395 extern objc_property_attribute_t *copyPropertyAttributeList(const char *attrs, unsigned int *outCount);
396 extern char *copyPropertyAttributeValue(const char *attrs, const char *name);
397
398 /* locking */
399 extern void lock_init(void);
400 extern rwlock_t selLock;
401 extern mutex_t cacheUpdateLock;
402 extern recursive_mutex_t loadMethodLock;
403 #if __OBJC2__
404 extern rwlock_t runtimeLock;
405 #else
406 extern mutex_t classLock;
407 extern mutex_t methodListLock;
408 #endif
409
410 /* Lock debugging */
411 #if defined(NDEBUG) || TARGET_OS_WIN32
412
413 #define mutex_lock(m) _mutex_lock_nodebug(m)
414 #define mutex_try_lock(m) _mutex_try_lock_nodebug(m)
415 #define mutex_unlock(m) _mutex_unlock_nodebug(m)
416 #define mutex_assert_locked(m) do { } while (0)
417 #define mutex_assert_unlocked(m) do { } while (0)
418
419 #define recursive_mutex_lock(m) _recursive_mutex_lock_nodebug(m)
420 #define recursive_mutex_try_lock(m) _recursive_mutex_try_lock_nodebug(m)
421 #define recursive_mutex_unlock(m) _recursive_mutex_unlock_nodebug(m)
422 #define recursive_mutex_assert_locked(m) do { } while (0)
423 #define recursive_mutex_assert_unlocked(m) do { } while (0)
424
425 #define monitor_enter(m) _monitor_enter_nodebug(m)
426 #define monitor_exit(m) _monitor_exit_nodebug(m)
427 #define monitor_wait(m) _monitor_wait_nodebug(m)
428 #define monitor_assert_locked(m) do { } while (0)
429 #define monitor_assert_unlocked(m) do { } while (0)
430
431 #define rwlock_read(m) _rwlock_read_nodebug(m)
432 #define rwlock_write(m) _rwlock_write_nodebug(m)
433 #define rwlock_try_read(m) _rwlock_try_read_nodebug(m)
434 #define rwlock_try_write(m) _rwlock_try_write_nodebug(m)
435 #define rwlock_unlock_read(m) _rwlock_unlock_read_nodebug(m)
436 #define rwlock_unlock_write(m) _rwlock_unlock_write_nodebug(m)
437 #define rwlock_assert_reading(m) do { } while (0)
438 #define rwlock_assert_writing(m) do { } while (0)
439 #define rwlock_assert_locked(m) do { } while (0)
440 #define rwlock_assert_unlocked(m) do { } while (0)
441
442 #else
443
444 extern int _mutex_lock_debug(mutex_t *lock, const char *name);
445 extern int _mutex_try_lock_debug(mutex_t *lock, const char *name);
446 extern int _mutex_unlock_debug(mutex_t *lock, const char *name);
447 extern void _mutex_assert_locked_debug(mutex_t *lock, const char *name);
448 extern void _mutex_assert_unlocked_debug(mutex_t *lock, const char *name);
449
450 extern int _recursive_mutex_lock_debug(recursive_mutex_t *lock, const char *name);
451 extern int _recursive_mutex_try_lock_debug(recursive_mutex_t *lock, const char *name);
452 extern int _recursive_mutex_unlock_debug(recursive_mutex_t *lock, const char *name);
453 extern void _recursive_mutex_assert_locked_debug(recursive_mutex_t *lock, const char *name);
454 extern void _recursive_mutex_assert_unlocked_debug(recursive_mutex_t *lock, const char *name);
455
456 extern int _monitor_enter_debug(monitor_t *lock, const char *name);
457 extern int _monitor_exit_debug(monitor_t *lock, const char *name);
458 extern int _monitor_wait_debug(monitor_t *lock, const char *name);
459 extern void _monitor_assert_locked_debug(monitor_t *lock, const char *name);
460 extern void _monitor_assert_unlocked_debug(monitor_t *lock, const char *name);
461
462 extern void _rwlock_read_debug(rwlock_t *l, const char *name);
463 extern void _rwlock_write_debug(rwlock_t *l, const char *name);
464 extern int _rwlock_try_read_debug(rwlock_t *l, const char *name);
465 extern int _rwlock_try_write_debug(rwlock_t *l, const char *name);
466 extern void _rwlock_unlock_read_debug(rwlock_t *l, const char *name);
467 extern void _rwlock_unlock_write_debug(rwlock_t *l, const char *name);
468 extern void _rwlock_assert_reading_debug(rwlock_t *l, const char *name);
469 extern void _rwlock_assert_writing_debug(rwlock_t *l, const char *name);
470 extern void _rwlock_assert_locked_debug(rwlock_t *l, const char *name);
471 extern void _rwlock_assert_unlocked_debug(rwlock_t *l, const char *name);
472
473 #define mutex_lock(m) _mutex_lock_debug (m, #m)
474 #define mutex_try_lock(m) _mutex_try_lock_debug (m, #m)
475 #define mutex_unlock(m) _mutex_unlock_debug (m, #m)
476 #define mutex_assert_locked(m) _mutex_assert_locked_debug (m, #m)
477 #define mutex_assert_unlocked(m) _mutex_assert_unlocked_debug (m, #m)
478
479 #define recursive_mutex_lock(m) _recursive_mutex_lock_debug (m, #m)
480 #define recursive_mutex_try_lock(m) _recursive_mutex_try_lock_debug (m, #m)
481 #define recursive_mutex_unlock(m) _recursive_mutex_unlock_debug (m, #m)
482 #define recursive_mutex_assert_locked(m) _recursive_mutex_assert_locked_debug (m, #m)
483 #define recursive_mutex_assert_unlocked(m) _recursive_mutex_assert_unlocked_debug (m, #m)
484
485 #define monitor_enter(m) _monitor_enter_debug(m, #m)
486 #define monitor_exit(m) _monitor_exit_debug(m, #m)
487 #define monitor_wait(m) _monitor_wait_debug(m, #m)
488 #define monitor_assert_locked(m) _monitor_assert_locked_debug(m, #m)
489 #define monitor_assert_unlocked(m) _monitor_assert_unlocked_debug(m, #m)
490
491 #define rwlock_read(m) _rwlock_read_debug(m, #m)
492 #define rwlock_write(m) _rwlock_write_debug(m, #m)
493 #define rwlock_try_read(m) _rwlock_try_read_debug(m, #m)
494 #define rwlock_try_write(m) _rwlock_try_write_debug(m, #m)
495 #define rwlock_unlock_read(m) _rwlock_unlock_read_debug(m, #m)
496 #define rwlock_unlock_write(m) _rwlock_unlock_write_debug(m, #m)
497 #define rwlock_assert_reading(m) _rwlock_assert_reading_debug(m, #m)
498 #define rwlock_assert_writing(m) _rwlock_assert_writing_debug(m, #m)
499 #define rwlock_assert_locked(m) _rwlock_assert_locked_debug(m, #m)
500 #define rwlock_assert_unlocked(m) _rwlock_assert_unlocked_debug(m, #m)
501
502 #endif
503
504 #define rwlock_unlock(m, s) \
505 do { \
506 if ((s) == RDONLY) rwlock_unlock_read(m); \
507 else if ((s) == RDWR) rwlock_unlock_write(m); \
508 } while (0)
509
510
511 #if !TARGET_OS_WIN32
512 /* nil handler object */
513 extern id _objc_nilReceiver;
514 extern id _objc_setNilReceiver(id newNilReceiver);
515 extern id _objc_getNilReceiver(void);
516 #endif
517
518 /* forward handler functions */
519 extern void *_objc_forward_handler;
520 extern void *_objc_forward_stret_handler;
521
522
523 /* ignored selector support */
524
525 /* Non-GC: no ignored selectors
526 GC (i386 Mac): some selectors ignored, remapped to kIgnore
527 GC (others): some selectors ignored, but not remapped
528 */
529
530 static inline int ignoreSelector(SEL sel)
531 {
532 #if !SUPPORT_GC
533 return NO;
534 #elif SUPPORT_IGNORED_SELECTOR_CONSTANT
535 return UseGC && sel == (SEL)kIgnore;
536 #else
537 return UseGC &&
538 (sel == @selector(retain) ||
539 sel == @selector(release) ||
540 sel == @selector(autorelease) ||
541 sel == @selector(retainCount) ||
542 sel == @selector(dealloc));
543 #endif
544 }
545
546 static inline int ignoreSelectorNamed(const char *sel)
547 {
548 #if !SUPPORT_GC
549 return NO;
550 #else
551 // release retain retainCount dealloc autorelease
552 return (UseGC &&
553 ( (sel[0] == 'r' && sel[1] == 'e' &&
554 (strcmp(&sel[2], "lease") == 0 ||
555 strcmp(&sel[2], "tain") == 0 ||
556 strcmp(&sel[2], "tainCount") == 0 ))
557 ||
558 (strcmp(sel, "dealloc") == 0)
559 ||
560 (sel[0] == 'a' && sel[1] == 'u' &&
561 strcmp(&sel[2], "torelease") == 0)));
562 #endif
563 }
564
565 /* GC startup */
566 extern void gc_init(BOOL wantsGC);
567 extern void gc_init2(void);
568
569 /* Exceptions */
570 struct alt_handler_list;
571 extern void exception_init(void);
572 extern void _destroyAltHandlerList(struct alt_handler_list *list);
573
574 /* Class change notifications (gdb only for now) */
575 #define OBJC_CLASS_ADDED (1<<0)
576 #define OBJC_CLASS_REMOVED (1<<1)
577 #define OBJC_CLASS_IVARS_CHANGED (1<<2)
578 #define OBJC_CLASS_METHODS_CHANGED (1<<3)
579 extern void gdb_objc_class_changed(Class cls, unsigned long changes, const char *classname)
580 __attribute__((noinline));
581
582 #if SUPPORT_GC
583
584 /* Write barrier implementations */
585 extern id objc_getAssociatedObject_non_gc(id object, const void *key);
586 extern void objc_setAssociatedObject_non_gc(id object, const void *key, id value, objc_AssociationPolicy policy);
587
588 extern id objc_getAssociatedObject_gc(id object, const void *key);
589 extern void objc_setAssociatedObject_gc(id object, const void *key, id value, objc_AssociationPolicy policy);
590
591 /* xrefs */
592 extern objc_xref_t _object_addExternalReference_non_gc(id obj, objc_xref_t type);
593 extern id _object_readExternalReference_non_gc(objc_xref_t ref);
594 extern void _object_removeExternalReference_non_gc(objc_xref_t ref);
595
596 extern objc_xref_t _object_addExternalReference_gc(id obj, objc_xref_t type);
597 extern id _object_readExternalReference_gc(objc_xref_t ref);
598 extern void _object_removeExternalReference_gc(objc_xref_t ref);
599
600 /* GC weak reference fixup. */
601 extern void gc_fixup_weakreferences(id newObject, id oldObject);
602
603 /* GC datasegment registration. */
604 extern void gc_register_datasegment(uintptr_t base, size_t size);
605 extern void gc_unregister_datasegment(uintptr_t base, size_t size);
606
607 /* objc_dumpHeap implementation */
608 extern BOOL _objc_dumpHeap(auto_zone_t *zone, const char *filename);
609
610 #endif
611
612
613 // Settings from environment variables
614 #define OPTION(var, env, help) extern bool var;
615 #include "objc-env.h"
616 #undef OPTION
617
618 extern void environ_init(void);
619
620 extern void logReplacedMethod(const char *className, SEL s, BOOL isMeta, const char *catName, IMP oldImp, IMP newImp);
621
622 static __inline uint32_t _objc_strhash(const char *s) {
623 uint32_t hash = 0;
624 for (;;) {
625 int a = *s++;
626 if (0 == a) break;
627 hash += (hash << 8) + a;
628 }
629 return hash;
630 }
631
632
633 // objc per-thread storage
634 typedef struct {
635 struct _objc_initializing_classes *initializingClasses; // for +initialize
636 struct SyncCache *syncCache; // for @synchronize
637 struct alt_handler_list *handlerList; // for exception alt handlers
638
639 // If you add new fields here, don't forget to update
640 // _objc_pthread_destroyspecific()
641
642 } _objc_pthread_data;
643
644 extern _objc_pthread_data *_objc_fetch_pthread_data(BOOL create);
645 extern void tls_init(void);
646
647 // encoding.h
648 extern unsigned int encoding_getNumberOfArguments(const char *typedesc);
649 extern unsigned int encoding_getSizeOfArguments(const char *typedesc);
650 extern unsigned int encoding_getArgumentInfo(const char *typedesc, unsigned int arg, const char **type, int *offset);
651 extern void encoding_getReturnType(const char *t, char *dst, size_t dst_len);
652 extern char * encoding_copyReturnType(const char *t);
653 extern void encoding_getArgumentType(const char *t, unsigned int index, char *dst, size_t dst_len);
654 extern char *encoding_copyArgumentType(const char *t, unsigned int index);
655
656 // sync.h
657 extern void _destroySyncCache(struct SyncCache *cache);
658
659 // arr
660 extern void arr_init(void);
661 extern id objc_autoreleaseReturnValue(id obj);
662
663
664 // layout.h
665 typedef struct {
666 uint8_t *bits;
667 size_t bitCount;
668 size_t bitsAllocated;
669 BOOL weak;
670 } layout_bitmap;
671 extern layout_bitmap layout_bitmap_create(const unsigned char *layout_string, size_t layoutStringInstanceSize, size_t instanceSize, BOOL weak);
672 extern layout_bitmap layout_bitmap_create_empty(size_t instanceSize, BOOL weak);
673 extern void layout_bitmap_free(layout_bitmap bits);
674 extern const unsigned char *layout_string_create(layout_bitmap bits);
675 extern void layout_bitmap_set_ivar(layout_bitmap bits, const char *type, size_t offset);
676 extern void layout_bitmap_grow(layout_bitmap *bits, size_t newCount);
677 extern void layout_bitmap_slide(layout_bitmap *bits, size_t oldPos, size_t newPos);
678 extern void layout_bitmap_slide_anywhere(layout_bitmap *bits, size_t oldPos, size_t newPos);
679 extern BOOL layout_bitmap_splat(layout_bitmap dst, layout_bitmap src,
680 size_t oldSrcInstanceSize);
681 extern BOOL layout_bitmap_or(layout_bitmap dst, layout_bitmap src, const char *msg);
682 extern BOOL layout_bitmap_clear(layout_bitmap dst, layout_bitmap src, const char *msg);
683 extern void layout_bitmap_print(layout_bitmap bits);
684
685
686 // fixme runtime
687 extern Class look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler);
688 extern const char *map_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
689 extern const char *map_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
690 extern const char * load_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
691 extern BOOL load_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
692 extern void unmap_image(const struct mach_header *mh, intptr_t vmaddr_slide);
693 extern void unmap_image_nolock(const struct mach_header *mh);
694 extern void _read_images(header_info **hList, uint32_t hCount);
695 extern void prepare_load_methods(header_info *hi);
696 extern void _unload_image(header_info *hi);
697 extern const char ** _objc_copyClassNamesForImage(header_info *hi, unsigned int *outCount);
698
699 extern Class _objc_allocateFutureClass(const char *name);
700
701
702 extern const header_info *_headerForClass(Class cls);
703
704 extern Class _class_remap(Class cls);
705 extern Class _class_getNonMetaClass(Class cls, id obj);
706 extern Ivar _class_getVariable(Class cls, const char *name, Class *memberOf);
707 extern BOOL _class_usesAutomaticRetainRelease(Class cls);
708 extern uint32_t _class_getInstanceStart(Class cls);
709
710 extern unsigned _class_createInstancesFromZone(Class cls, size_t extraBytes, void *zone, id *results, unsigned num_requested);
711 extern id _objc_constructOrFree(Class cls, void *bytes);
712
713 extern const char *_category_getName(Category cat);
714 extern const char *_category_getClassName(Category cat);
715 extern Class _category_getClass(Category cat);
716 extern IMP _category_getLoadMethod(Category cat);
717
718 extern BOOL object_cxxConstruct(id obj);
719 extern void object_cxxDestruct(id obj);
720
721 extern void _class_resolveMethod(Class cls, SEL sel, id inst);
722
723 #define OBJC_WARN_DEPRECATED \
724 do { \
725 static int warned = 0; \
726 if (!warned) { \
727 warned = 1; \
728 _objc_inform_deprecated(__FUNCTION__, NULL); \
729 } \
730 } while (0) \
731
732 __END_DECLS
733
734
735 #ifndef STATIC_ASSERT
736 # define STATIC_ASSERT(x) _STATIC_ASSERT2(x, __LINE__)
737 # define _STATIC_ASSERT2(x, line) _STATIC_ASSERT3(x, line)
738 # define _STATIC_ASSERT3(x, line) \
739 typedef struct { \
740 int _static_assert[(x) ? 0 : -1]; \
741 } _static_assert_ ## line __attribute__((unavailable))
742 #endif
743
744
745 // Global operator new and delete. We must not use any app overrides.
746 // This ALSO REQUIRES each of these be in libobjc's unexported symbol list.
747 #if __cplusplus
748 #include <new>
749 inline void* operator new(std::size_t size) throw (std::bad_alloc) { return _malloc_internal(size); }
750 inline void* operator new[](std::size_t size) throw (std::bad_alloc) { return _malloc_internal(size); }
751 inline void* operator new(std::size_t size, const std::nothrow_t&) throw() { return _malloc_internal(size); }
752 inline void* operator new[](std::size_t size, const std::nothrow_t&) throw() { return _malloc_internal(size); }
753 inline void operator delete(void* p) throw() { _free_internal(p); }
754 inline void operator delete[](void* p) throw() { _free_internal(p); }
755 inline void operator delete(void* p, const std::nothrow_t&) throw() { _free_internal(p); }
756 inline void operator delete[](void* p, const std::nothrow_t&) throw() { _free_internal(p); }
757 #endif
758
759
760 #endif /* _OBJC_PRIVATE_H_ */
761