]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-private.h
837d4e1f4c0ffea1f2797ed7f16fc88a0c4d18b0
[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-os.h"
32
33 #include "objc.h"
34 #include "runtime.h"
35 #include "maptable.h"
36 #include "hashtable2.h"
37 #include "objc-api.h"
38 #include "objc-config.h"
39 #include "objc-references.h"
40 #include "objc-initialize.h"
41 #include "objc-loadmethod.h"
42 #include "objc-internal.h"
43 #include "objc-abi.h"
44
45 #include "objc-auto.h"
46
47 #define __APPLE_API_PRIVATE
48 #include "objc-gdb.h"
49 #undef __APPLE_API_PRIVATE
50
51 /* Do not include message.h here. */
52 /* #include "message.h" */
53
54
55 __BEGIN_DECLS
56
57 #ifdef __LP64__
58 # define WORD_SHIFT 3UL
59 # define WORD_MASK 7UL
60 #else
61 # define WORD_SHIFT 2UL
62 # define WORD_MASK 3UL
63 #endif
64
65 #if (defined(OBJC_NO_GC) && SUPPORT_GC) || \
66 (!defined(OBJC_NO_GC) && !SUPPORT_GC)
67 # error OBJC_NO_GC and SUPPORT_GC inconsistent
68 #endif
69
70 #if SUPPORT_GC
71 # include <auto_zone.h>
72 extern PRIVATE_EXTERN BOOL UseGC; // equivalent to calling objc_collecting_enabled()
73 extern PRIVATE_EXTERN BOOL UseCompaction; // if binary has opted-in for compaction.
74 extern PRIVATE_EXTERN auto_zone_t *gc_zone; // the GC zone, or NULL if no GC
75 extern void objc_addRegisteredClass(Class c);
76 extern void objc_removeRegisteredClass(Class c);
77 extern void objc_disableCompaction();
78 #else
79 # define UseGC NO
80 # define UseCompaction NO
81 # define gc_zone NULL
82 # define objc_assign_ivar_internal objc_assign_ivar
83 # define objc_addRegisteredClass(c) do {} while(0)
84 # define objc_removeRegisteredClass(c) do {} while(0)
85 /* Uses of the following must be protected with UseGC. */
86 extern id gc_unsupported_dont_call();
87 # define auto_zone_allocate_object gc_unsupported_dont_call
88 # define auto_zone_retain gc_unsupported_dont_call
89 # define auto_zone_release gc_unsupported_dont_call
90 # define auto_zone_is_valid_pointer gc_unsupported_dont_call
91 # define auto_zone_write_barrier_memmove gc_unsupported_dont_call
92 # define AUTO_OBJECT_SCANNED 0
93 #endif
94
95 #if __OBJC2__
96 typedef struct objc_cache *Cache;
97 #else
98 // definition in runtime.h
99 #endif
100
101
102 typedef struct {
103 uint32_t version; // currently 0
104 uint32_t flags;
105 } objc_image_info;
106
107 // masks for objc_image_info.flags
108 #define OBJC_IMAGE_IS_REPLACEMENT (1<<0)
109 #define OBJC_IMAGE_SUPPORTS_GC (1<<1)
110 #define OBJC_IMAGE_REQUIRES_GC (1<<2)
111 #define OBJC_IMAGE_OPTIMIZED_BY_DYLD (1<<3)
112 #define OBJC_IMAGE_SUPPORTS_COMPACTION (1<<4)
113
114
115 #define _objcHeaderIsReplacement(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_IS_REPLACEMENT))
116
117 /* OBJC_IMAGE_IS_REPLACEMENT:
118 Don't load any classes
119 Don't load any categories
120 Do fix up selector refs (@selector points to them)
121 Do fix up class refs (@class and objc_msgSend points to them)
122 Do fix up protocols (@protocol points to them)
123 Do fix up super_class pointers in classes ([super ...] points to them)
124 Future: do load new classes?
125 Future: do load new categories?
126 Future: do insert new methods on existing classes?
127 Future: do insert new methods on existing categories?
128 */
129
130 #define _objcInfoSupportsGC(info) (((info)->flags & OBJC_IMAGE_SUPPORTS_GC) ? 1 : 0)
131 #define _objcInfoRequiresGC(info) (((info)->flags & OBJC_IMAGE_REQUIRES_GC) ? 1 : 0)
132 #define _objcInfoSupportsCompaction(info) (((info)->flags & OBJC_IMAGE_SUPPORTS_COMPACTION) ? 1 : 0)
133 #define _objcHeaderSupportsGC(h) ((h)->info && _objcInfoSupportsGC((h)->info))
134 #define _objcHeaderRequiresGC(h) ((h)->info && _objcInfoRequiresGC((h)->info))
135 #define _objcHeaderSupportsCompaction(h) ((h)->info && _objcInfoSupportsCompaction((h)->info))
136
137 /* OBJC_IMAGE_SUPPORTS_GC:
138 was compiled with -fobjc-gc flag, regardless of whether write-barriers were issued
139 if executable image compiled this way, then all subsequent libraries etc. must also be this way
140 */
141
142 #define _objcHeaderOptimizedByDyld(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_OPTIMIZED_BY_DYLD))
143
144 /* OBJC_IMAGE_OPTIMIZED_BY_DYLD:
145 Assorted metadata precooked in the dyld shared cache.
146 Never set for images outside the shared cache file itself.
147 */
148
149
150 typedef struct _header_info {
151 struct _header_info *next;
152 const headerType * mhdr;
153 struct objc_module *mod_ptr;
154 size_t mod_count;
155 const objc_image_info *info;
156 BOOL allClassesRealized;
157 os_header_info os;
158 } header_info;
159
160 extern header_info *FirstHeader;
161 extern header_info *LastHeader;
162 extern int HeaderCount;
163
164 extern void _objc_appendHeader(header_info *hi);
165 extern void _objc_removeHeader(header_info *hi);
166 extern const char *_nameForHeader(const headerType*);
167
168 extern objc_image_info *_getObjcImageInfo(const headerType *head, size_t *size);
169 extern const char *_getObjcHeaderName(const headerType *head);
170 extern BOOL _hasObjcContents(const header_info *hi);
171
172
173 /* selectors */
174 extern void sel_init(BOOL gc);
175 extern SEL sel_registerNameNoLock(const char *str, BOOL copy);
176 extern void sel_lock(void);
177 extern void sel_unlock(void);
178 extern BOOL sel_preoptimizationValid(const header_info *hi);
179 extern void disableSharedCacheOptimizations(void);
180
181 extern SEL SEL_load;
182 extern SEL SEL_initialize;
183 extern SEL SEL_resolveClassMethod;
184 extern SEL SEL_resolveInstanceMethod;
185 extern SEL SEL_cxx_construct;
186 extern SEL SEL_cxx_destruct;
187 extern SEL SEL_retain;
188 extern SEL SEL_release;
189 extern SEL SEL_autorelease;
190 extern SEL SEL_retainCount;
191 extern SEL SEL_alloc;
192 extern SEL SEL_copy;
193 extern SEL SEL_new;
194 extern SEL SEL_finalize;
195 extern SEL SEL_forwardInvocation;
196
197
198 /* optional malloc zone for runtime data */
199 extern malloc_zone_t *_objc_internal_zone(void);
200 extern void *_malloc_internal(size_t size);
201 extern void *_calloc_internal(size_t count, size_t size);
202 extern void *_realloc_internal(void *ptr, size_t size);
203 extern char *_strdup_internal(const char *str);
204 extern char *_strdupcat_internal(const char *s1, const char *s2);
205 extern uint8_t *_ustrdup_internal(const uint8_t *str);
206 extern void *_memdup_internal(const void *mem, size_t size);
207 extern void _free_internal(void *ptr);
208 extern size_t _malloc_size_internal(void *ptr);
209
210 extern Class _calloc_class(size_t size);
211
212 extern IMP lookUpMethod(Class, SEL, BOOL initialize, BOOL cache);
213 extern void lockForMethodLookup(void);
214 extern void unlockForMethodLookup(void);
215 extern IMP prepareForMethodLookup(Class cls, SEL sel, BOOL initialize);
216
217 extern IMP _cache_getImp(Class cls, SEL sel);
218 extern Method _cache_getMethod(Class cls, SEL sel, IMP objc_msgForward_internal_imp);
219
220 /* message dispatcher */
221 extern IMP _class_lookupMethodAndLoadCache3(id, SEL, Class);
222 extern id _objc_msgForward_internal(id self, SEL sel, ...);
223 extern id _objc_ignored_method(id self, SEL _cmd);
224
225 /* errors */
226 extern void __objc_error(id, const char *, ...) __attribute__((format (printf, 2, 3), noreturn));
227 extern void _objc_inform(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
228 extern void _objc_inform_on_crash(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
229 extern void _objc_inform_now_and_on_crash(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
230 extern void _objc_inform_deprecated(const char *oldname, const char *newname) __attribute__((noinline));
231 extern void inform_duplicate(const char *name, Class oldCls, Class cls);
232 extern bool crashlog_header_name(header_info *hi);
233 extern bool crashlog_header_name_string(const char *name);
234
235 /* magic */
236 extern Class _objc_getFreedObjectClass (void);
237
238 /* map table additions */
239 extern void *NXMapKeyCopyingInsert(NXMapTable *table, const void *key, const void *value);
240 extern void *NXMapKeyFreeingRemove(NXMapTable *table, const void *key);
241
242 /* property attribute parsing */
243 extern const char *copyPropertyAttributeString(const objc_property_attribute_t *attrs, unsigned int count);
244 extern objc_property_attribute_t *copyPropertyAttributeList(const char *attrs, unsigned int *outCount);
245 extern char *copyPropertyAttributeValue(const char *attrs, const char *name);
246
247
248 /* locking */
249 /* Every lock used anywhere must be declared here.
250 * Locks not declared here may cause gdb deadlocks. */
251 extern void lock_init(void);
252 extern rwlock_t selLock;
253 extern mutex_t cacheUpdateLock;
254 extern recursive_mutex_t loadMethodLock;
255 #if __OBJC2__
256 extern rwlock_t runtimeLock;
257 #else
258 extern mutex_t classLock;
259 extern mutex_t methodListLock;
260 #endif
261
262 /* Debugger mode for gdb */
263 #define DEBUGGER_OFF 0
264 #define DEBUGGER_PARTIAL 1
265 #define DEBUGGER_FULL 2
266 extern int startDebuggerMode(void);
267 extern void endDebuggerMode(void);
268
269 #if defined(NDEBUG) || TARGET_OS_WIN32
270
271 #define mutex_lock(m) _mutex_lock_nodebug(m)
272 #define mutex_try_lock(m) _mutex_try_lock_nodebug(m)
273 #define mutex_unlock(m) _mutex_unlock_nodebug(m)
274 #define mutex_assert_locked(m) do { } while (0)
275 #define mutex_assert_unlocked(m) do { } while (0)
276
277 #define recursive_mutex_lock(m) _recursive_mutex_lock_nodebug(m)
278 #define recursive_mutex_try_lock(m) _recursive_mutex_try_lock_nodebug(m)
279 #define recursive_mutex_unlock(m) _recursive_mutex_unlock_nodebug(m)
280 #define recursive_mutex_assert_locked(m) do { } while (0)
281 #define recursive_mutex_assert_unlocked(m) do { } while (0)
282
283 #define monitor_enter(m) _monitor_enter_nodebug(m)
284 #define monitor_exit(m) _monitor_exit_nodebug(m)
285 #define monitor_wait(m) _monitor_wait_nodebug(m)
286 #define monitor_assert_locked(m) do { } while (0)
287 #define monitor_assert_unlocked(m) do { } while (0)
288
289 #define rwlock_read(m) _rwlock_read_nodebug(m)
290 #define rwlock_write(m) _rwlock_write_nodebug(m)
291 #define rwlock_try_read(m) _rwlock_try_read_nodebug(m)
292 #define rwlock_try_write(m) _rwlock_try_write_nodebug(m)
293 #define rwlock_unlock_read(m) _rwlock_unlock_read_nodebug(m)
294 #define rwlock_unlock_write(m) _rwlock_unlock_write_nodebug(m)
295 #define rwlock_assert_reading(m) do { } while (0)
296 #define rwlock_assert_writing(m) do { } while (0)
297 #define rwlock_assert_locked(m) do { } while (0)
298 #define rwlock_assert_unlocked(m) do { } while (0)
299
300 #else
301
302 extern int _mutex_lock_debug(mutex_t *lock, const char *name);
303 extern int _mutex_try_lock_debug(mutex_t *lock, const char *name);
304 extern int _mutex_unlock_debug(mutex_t *lock, const char *name);
305 extern void _mutex_assert_locked_debug(mutex_t *lock, const char *name);
306 extern void _mutex_assert_unlocked_debug(mutex_t *lock, const char *name);
307
308 extern int _recursive_mutex_lock_debug(recursive_mutex_t *lock, const char *name);
309 extern int _recursive_mutex_try_lock_debug(recursive_mutex_t *lock, const char *name);
310 extern int _recursive_mutex_unlock_debug(recursive_mutex_t *lock, const char *name);
311 extern void _recursive_mutex_assert_locked_debug(recursive_mutex_t *lock, const char *name);
312 extern void _recursive_mutex_assert_unlocked_debug(recursive_mutex_t *lock, const char *name);
313
314 extern int _monitor_enter_debug(monitor_t *lock, const char *name);
315 extern int _monitor_exit_debug(monitor_t *lock, const char *name);
316 extern int _monitor_wait_debug(monitor_t *lock, const char *name);
317 extern void _monitor_assert_locked_debug(monitor_t *lock, const char *name);
318 extern void _monitor_assert_unlocked_debug(monitor_t *lock, const char *name);
319
320 extern void _rwlock_read_debug(rwlock_t *l, const char *name);
321 extern void _rwlock_write_debug(rwlock_t *l, const char *name);
322 extern int _rwlock_try_read_debug(rwlock_t *l, const char *name);
323 extern int _rwlock_try_write_debug(rwlock_t *l, const char *name);
324 extern void _rwlock_unlock_read_debug(rwlock_t *l, const char *name);
325 extern void _rwlock_unlock_write_debug(rwlock_t *l, const char *name);
326 extern void _rwlock_assert_reading_debug(rwlock_t *l, const char *name);
327 extern void _rwlock_assert_writing_debug(rwlock_t *l, const char *name);
328 extern void _rwlock_assert_locked_debug(rwlock_t *l, const char *name);
329 extern void _rwlock_assert_unlocked_debug(rwlock_t *l, const char *name);
330
331 #define mutex_lock(m) _mutex_lock_debug (m, #m)
332 #define mutex_try_lock(m) _mutex_try_lock_debug (m, #m)
333 #define mutex_unlock(m) _mutex_unlock_debug (m, #m)
334 #define mutex_assert_locked(m) _mutex_assert_locked_debug (m, #m)
335 #define mutex_assert_unlocked(m) _mutex_assert_unlocked_debug (m, #m)
336
337 #define recursive_mutex_lock(m) _recursive_mutex_lock_debug (m, #m)
338 #define recursive_mutex_try_lock(m) _recursive_mutex_try_lock_debug (m, #m)
339 #define recursive_mutex_unlock(m) _recursive_mutex_unlock_debug (m, #m)
340 #define recursive_mutex_assert_locked(m) _recursive_mutex_assert_locked_debug (m, #m)
341 #define recursive_mutex_assert_unlocked(m) _recursive_mutex_assert_unlocked_debug (m, #m)
342
343 #define monitor_enter(m) _monitor_enter_debug(m, #m)
344 #define monitor_exit(m) _monitor_exit_debug(m, #m)
345 #define monitor_wait(m) _monitor_wait_debug(m, #m)
346 #define monitor_assert_locked(m) _monitor_assert_locked_debug(m, #m)
347 #define monitor_assert_unlocked(m) _monitor_assert_unlocked_debug(m, #m)
348
349 #define rwlock_read(m) _rwlock_read_debug(m, #m)
350 #define rwlock_write(m) _rwlock_write_debug(m, #m)
351 #define rwlock_try_read(m) _rwlock_try_read_debug(m, #m)
352 #define rwlock_try_write(m) _rwlock_try_write_debug(m, #m)
353 #define rwlock_unlock_read(m) _rwlock_unlock_read_debug(m, #m)
354 #define rwlock_unlock_write(m) _rwlock_unlock_write_debug(m, #m)
355 #define rwlock_assert_reading(m) _rwlock_assert_reading_debug(m, #m)
356 #define rwlock_assert_writing(m) _rwlock_assert_writing_debug(m, #m)
357 #define rwlock_assert_locked(m) _rwlock_assert_locked_debug(m, #m)
358 #define rwlock_assert_unlocked(m) _rwlock_assert_unlocked_debug(m, #m)
359
360 #endif
361
362 #define rwlock_unlock(m, s) \
363 do { \
364 if ((s) == RDONLY) rwlock_unlock_read(m); \
365 else if ((s) == RDWR) rwlock_unlock_write(m); \
366 } while (0)
367
368
369 extern NXHashTable *class_hash;
370
371 #if !TARGET_OS_WIN32
372 /* nil handler object */
373 extern id _objc_nilReceiver;
374 extern id _objc_setNilReceiver(id newNilReceiver);
375 extern id _objc_getNilReceiver(void);
376 #endif
377
378 /* forward handler functions */
379 extern void *_objc_forward_handler;
380 extern void *_objc_forward_stret_handler;
381
382 /* tagged pointer support */
383 #if SUPPORT_TAGGED_POINTERS
384
385 #define OBJC_IS_TAGGED_PTR(PTR) ((uintptr_t)(PTR) & 0x1)
386 extern Class _objc_tagged_isa_table[16];
387
388 #else
389
390 #define OBJC_IS_TAGGED_PTR(PTR) 0
391
392 #endif
393
394
395 /* ignored selector support */
396
397 /* Non-GC: no ignored selectors
398 GC without fixup dispatch: some selectors ignored, remapped to kIgnore
399 GC with fixup dispatch: some selectors ignored, but not remapped
400 */
401
402 static inline int ignoreSelector(SEL sel)
403 {
404 #if !SUPPORT_GC
405 return NO;
406 #elif SUPPORT_IGNORED_SELECTOR_CONSTANT
407 return UseGC && sel == (SEL)kIgnore;
408 #else
409 return UseGC &&
410 (sel == @selector(retain) ||
411 sel == @selector(release) ||
412 sel == @selector(autorelease) ||
413 sel == @selector(retainCount) ||
414 sel == @selector(dealloc));
415 #endif
416 }
417
418 static inline int ignoreSelectorNamed(const char *sel)
419 {
420 #if !SUPPORT_GC
421 return NO;
422 #else
423 // release retain retainCount dealloc autorelease
424 return (UseGC &&
425 ( (sel[0] == 'r' && sel[1] == 'e' &&
426 (strcmp(&sel[2], "lease") == 0 ||
427 strcmp(&sel[2], "tain") == 0 ||
428 strcmp(&sel[2], "tainCount") == 0 ))
429 ||
430 (strcmp(sel, "dealloc") == 0)
431 ||
432 (sel[0] == 'a' && sel[1] == 'u' &&
433 strcmp(&sel[2], "torelease") == 0)));
434 #endif
435 }
436
437 /* Protocol implementation */
438 #if !__OBJC2__
439 struct old_protocol;
440 PRIVATE_EXTERN struct objc_method_description * lookup_protocol_method(struct old_protocol *proto, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod);
441 #else
442 PRIVATE_EXTERN Method _protocol_getMethod(Protocol *p, SEL sel, BOOL isRequiredMethod, BOOL isInstanceMethod);
443 #endif
444
445 /* GC and RTP startup */
446 extern void gc_init(BOOL wantsGC, BOOL wantsCompaction);
447 extern void rtp_init(void);
448
449 /* Exceptions */
450 struct alt_handler_list;
451 extern void exception_init(void);
452 extern void _destroyAltHandlerList(struct alt_handler_list *list);
453
454 /* Class change notifications (gdb only for now) */
455 #define OBJC_CLASS_ADDED (1<<0)
456 #define OBJC_CLASS_REMOVED (1<<1)
457 #define OBJC_CLASS_IVARS_CHANGED (1<<2)
458 #define OBJC_CLASS_METHODS_CHANGED (1<<3)
459 extern void gdb_objc_class_changed(Class cls, unsigned long changes, const char *classname)
460 __attribute__((noinline));
461
462 /* Write barrier implementations */
463 extern id objc_assign_strongCast_non_gc(id value, id *dest);
464 extern id objc_assign_global_non_gc(id value, id *dest);
465 extern id objc_assign_threadlocal_non_gc(id value, id *dest);
466 extern id objc_assign_ivar_non_gc(id value, id dest, ptrdiff_t offset);
467 extern id objc_assign_strongCast_gc(id val, id *dest);
468 extern id objc_assign_global_gc(id val, id *dest);
469 extern id objc_assign_threadlocal_gc(id val, id *dest);
470 extern id objc_assign_ivar_gc(id value, id dest, ptrdiff_t offset);
471
472 extern id objc_getAssociatedObject_non_gc(id object, const void *key);
473 extern void objc_setAssociatedObject_non_gc(id object, const void *key, id value, objc_AssociationPolicy policy);
474 extern id objc_getAssociatedObject_gc(id object, const void *key);
475 extern void objc_setAssociatedObject_gc(id object, const void *key, id value, objc_AssociationPolicy policy);
476
477 #if SUPPORT_GC
478
479 /* GC weak reference fixup. */
480 extern void gc_fixup_weakreferences(id newObject, id oldObject);
481
482 /* GC datasegment registration. */
483 extern void gc_register_datasegment(uintptr_t base, size_t size);
484 extern void gc_unregister_datasegment(uintptr_t base, size_t size);
485 extern void gc_fixup_barrier_stubs(const struct dyld_image_info *info);
486
487 /* objc_dumpHeap implementation */
488 extern BOOL _objc_dumpHeap(auto_zone_t *zone, const char *filename);
489
490 /*
491 objc_assign_ivar, objc_assign_global, objc_assign_threadlocal, and objc_assign_strongCast MUST NOT be called directly
492 from inside libobjc. They live in the data segment, and must be called through the
493 following pointer(s) for libobjc to exist in the shared cache.
494
495 Note: If we build with GC enabled, gcc will emit calls to the original functions, which will break this.
496 */
497
498 extern id (*objc_assign_ivar_internal)(id, id, ptrdiff_t);
499
500 #endif
501
502 /* Code modification */
503 extern size_t objc_branch_size(void *entry, void *target);
504 extern size_t objc_write_branch(void *entry, void *target);
505 extern size_t objc_cond_branch_size(void *entry, void *target, unsigned cond);
506 extern size_t objc_write_cond_branch(void *entry, void *target, unsigned cond);
507 #if defined(__i386__) || defined(__x86_64__)
508 #define COND_ALWAYS 0xE9 /* JMP rel32 */
509 #define COND_NE 0x85 /* JNE rel32 (0F 85) */
510 #endif
511
512
513 // Settings from environment variables
514 #if !SUPPORT_ENVIRON
515 # define ENV(x) enum { x = 0 }
516 #else
517 # define ENV(x) extern int x
518 #endif
519 ENV(PrintImages); // env OBJC_PRINT_IMAGES
520 ENV(PrintLoading); // env OBJC_PRINT_LOAD_METHODS
521 ENV(PrintInitializing); // env OBJC_PRINT_INITIALIZE_METHODS
522 ENV(PrintResolving); // env OBJC_PRINT_RESOLVED_METHODS
523 ENV(PrintConnecting); // env OBJC_PRINT_CLASS_SETUP
524 ENV(PrintProtocols); // env OBJC_PRINT_PROTOCOL_SETUP
525 ENV(PrintIvars); // env OBJC_PRINT_IVAR_SETUP
526 ENV(PrintVtables); // env OBJC_PRINT_VTABLE_SETUP
527 ENV(PrintVtableImages); // env OBJC_PRINT_VTABLE_IMAGES
528 ENV(PrintFuture); // env OBJC_PRINT_FUTURE_CLASSES
529 ENV(PrintRTP); // env OBJC_PRINT_RTP
530 ENV(PrintGC); // env OBJC_PRINT_GC
531 ENV(PrintPreopt); // env OBJC_PRINT_PREOPTIMIZATION
532 ENV(PrintCxxCtors); // env OBJC_PRINT_CXX_CTORS
533 ENV(PrintExceptions); // env OBJC_PRINT_EXCEPTIONS
534 ENV(PrintExceptionThrow); // env OBJC_PRINT_EXCEPTION_THROW
535 ENV(PrintAltHandlers); // env OBJC_PRINT_ALT_HANDLERS
536 ENV(PrintDeprecation); // env OBJC_PRINT_DEPRECATION_WARNINGS
537 ENV(PrintReplacedMethods); // env OBJC_PRINT_REPLACED_METHODS
538 ENV(PrintCaches); // env OBJC_PRINT_CACHE_SETUP
539 ENV(PrintPoolHiwat); // env OBJC_PRINT_POOL_HIGHWATER
540 ENV(UseInternalZone); // env OBJC_USE_INTERNAL_ZONE
541
542 ENV(DebugUnload); // env OBJC_DEBUG_UNLOAD
543 ENV(DebugFragileSuperclasses); // env OBJC_DEBUG_FRAGILE_SUPERCLASSES
544 ENV(DebugFinalizers); // env OBJC_DEBUG_FINALIZERS
545 ENV(DebugNilSync); // env OBJC_DEBUG_NIL_SYNC
546 ENV(DebugNonFragileIvars); // env OBJC_DEBUG_NONFRAGILE_IVARS
547 ENV(DebugAltHandlers); // env OBJC_DEBUG_ALT_HANDLERS
548
549 ENV(DisableGC); // env OBJC_DISABLE_GC
550 ENV(DisableVtables); // env OBJC_DISABLE_VTABLES
551 ENV(DisablePreopt); // env OBJC_DISABLE_PREOPTIMIZATION
552
553 #undef ENV
554
555 extern void environ_init(void);
556
557 extern void logReplacedMethod(const char *className, SEL s, BOOL isMeta, const char *catName, IMP oldImp, IMP newImp);
558
559 static __inline uint32_t _objc_strhash(const char *s) {
560 uint32_t hash = 0;
561 for (;;) {
562 int a = *s++;
563 if (0 == a) break;
564 hash += (hash << 8) + a;
565 }
566 return hash;
567 }
568
569
570 // objc per-thread storage
571 typedef struct {
572 struct _objc_initializing_classes *initializingClasses; // for +initialize
573 struct SyncCache *syncCache; // for @synchronize
574 struct alt_handler_list *handlerList; // for exception alt handlers
575
576 // If you add new fields here, don't forget to update
577 // _objc_pthread_destroyspecific()
578
579 } _objc_pthread_data;
580
581 extern _objc_pthread_data *_objc_fetch_pthread_data(BOOL create);
582 extern void tls_init(void);
583
584
585 // cache.h
586 #if TARGET_OS_WIN32
587
588 #else
589 static inline int isPowerOf2(unsigned long l) { return 1 == __builtin_popcountl(l); }
590 #endif
591 extern void flush_caches(Class cls, BOOL flush_meta);
592 extern void flush_cache(Class cls);
593 extern BOOL _cache_fill(Class cls, Method smt, SEL sel);
594 extern void _cache_addForwardEntry(Class cls, SEL sel);
595 extern IMP _cache_addIgnoredEntry(Class cls, SEL sel);
596 extern void _cache_free(Cache cache);
597 extern void _cache_collect(bool collectALot);
598
599 extern mutex_t cacheUpdateLock;
600
601 // encoding.h
602 extern unsigned int encoding_getNumberOfArguments(const char *typedesc);
603 extern unsigned int encoding_getSizeOfArguments(const char *typedesc);
604 extern unsigned int encoding_getArgumentInfo(const char *typedesc, int arg, const char **type, int *offset);
605 extern void encoding_getReturnType(const char *t, char *dst, size_t dst_len);
606 extern char * encoding_copyReturnType(const char *t);
607 extern void encoding_getArgumentType(const char *t, unsigned int index, char *dst, size_t dst_len);
608 extern char *encoding_copyArgumentType(const char *t, unsigned int index);
609
610 // sync.h
611 extern void _destroySyncCache(struct SyncCache *cache);
612
613 // arr
614 extern void (^objc_arr_log)(const char *, id param);
615 extern void arr_init(void);
616 extern id objc_autoreleaseReturnValue(id obj);
617
618
619 // layout.h
620 typedef struct {
621 uint8_t *bits;
622 size_t bitCount;
623 size_t bitsAllocated;
624 BOOL weak;
625 } layout_bitmap;
626 extern layout_bitmap layout_bitmap_create(const unsigned char *layout_string, size_t layoutStringInstanceSize, size_t instanceSize, BOOL weak);
627 extern layout_bitmap layout_bitmap_create_empty(size_t instanceSize, BOOL weak);
628 extern void layout_bitmap_free(layout_bitmap bits);
629 extern const unsigned char *layout_string_create(layout_bitmap bits);
630 extern void layout_bitmap_set_ivar(layout_bitmap bits, const char *type, size_t offset);
631 extern void layout_bitmap_grow(layout_bitmap *bits, size_t newCount);
632 extern void layout_bitmap_slide(layout_bitmap *bits, size_t oldPos, size_t newPos);
633 extern void layout_bitmap_slide_anywhere(layout_bitmap *bits, size_t oldPos, size_t newPos);
634 extern BOOL layout_bitmap_splat(layout_bitmap dst, layout_bitmap src,
635 size_t oldSrcInstanceSize);
636 extern BOOL layout_bitmap_or(layout_bitmap dst, layout_bitmap src, const char *msg);
637 extern BOOL layout_bitmap_clear(layout_bitmap dst, layout_bitmap src, const char *msg);
638 extern void layout_bitmap_print(layout_bitmap bits);
639
640
641 // fixme runtime
642 extern id look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler);
643 extern const char *map_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
644 extern const char *map_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
645 extern const char * load_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
646 extern BOOL load_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
647 extern void unmap_image(const struct mach_header *mh, intptr_t vmaddr_slide);
648 extern void unmap_image_nolock(const struct mach_header *mh);
649 extern void _read_images(header_info **hList, uint32_t hCount);
650 extern void prepare_load_methods(header_info *hi);
651 extern void _unload_image(header_info *hi);
652 extern const char ** _objc_copyClassNamesForImage(header_info *hi, unsigned int *outCount);
653
654 extern Class _objc_allocateFutureClass(const char *name);
655
656
657 extern const header_info *_headerForClass(Class cls);
658
659 extern Class _class_getSuperclass(Class cls);
660 extern BOOL _class_getInfo(Class cls, int info);
661 extern const char *_class_getName(Class cls);
662 extern size_t _class_getInstanceSize(Class cls);
663 extern Class _class_getMeta(Class cls);
664 extern BOOL _class_isMetaClass(Class cls);
665 extern Cache _class_getCache(Class cls);
666 extern void _class_setCache(Class cls, Cache cache);
667 extern BOOL _class_isInitializing(Class cls);
668 extern BOOL _class_isInitialized(Class cls);
669 extern void _class_setInitializing(Class cls);
670 extern void _class_setInitialized(Class cls);
671 extern Class _class_getNonMetaClass(Class cls);
672 extern Method _class_getMethod(Class cls, SEL sel);
673 extern Method _class_getMethodNoSuper(Class cls, SEL sel);
674 extern Method _class_getMethodNoSuper_nolock(Class cls, SEL sel);
675 extern BOOL _class_isLoadable(Class cls);
676 extern IMP _class_getLoadMethod(Class cls);
677 extern BOOL _class_hasLoadMethod(Class cls);
678 extern BOOL _class_hasCxxStructors(Class cls);
679 extern BOOL _class_shouldFinalizeOnMainThread(Class cls);
680 extern void _class_setFinalizeOnMainThread(Class cls);
681 extern BOOL _class_instancesHaveAssociatedObjects(Class cls);
682 extern void _class_setInstancesHaveAssociatedObjects(Class cls);
683 extern BOOL _class_shouldGrowCache(Class cls);
684 extern void _class_setGrowCache(Class cls, BOOL grow);
685 extern Ivar _class_getVariable(Class cls, const char *name, Class *memberOf);
686 extern BOOL _class_usesAutomaticRetainRelease(Class cls);
687 extern uint32_t _class_getInstanceStart(Class cls);
688
689 extern unsigned _class_createInstancesFromZone(Class cls, size_t extraBytes, void *zone, id *results, unsigned num_requested);
690 extern id _objc_constructOrFree(Class cls, void *bytes);
691
692 extern const char *_category_getName(Category cat);
693 extern const char *_category_getClassName(Category cat);
694 extern Class _category_getClass(Category cat);
695 extern IMP _category_getLoadMethod(Category cat);
696
697 extern BOOL object_cxxConstruct(id obj);
698 extern void object_cxxDestruct(id obj);
699
700 extern Method _class_resolveMethod(Class cls, SEL sel);
701 extern void log_and_fill_cache(Class cls, Class implementer, Method meth, SEL sel);
702
703 #define OBJC_WARN_DEPRECATED \
704 do { \
705 static int warned = 0; \
706 if (!warned) { \
707 warned = 1; \
708 _objc_inform_deprecated(__FUNCTION__, NULL); \
709 } \
710 } while (0) \
711
712 __END_DECLS
713
714
715 #ifndef STATIC_ASSERT
716 # define STATIC_ASSERT(x) _STATIC_ASSERT2(x, __LINE__)
717 # define _STATIC_ASSERT2(x, line) _STATIC_ASSERT3(x, line)
718 # define _STATIC_ASSERT3(x, line) \
719 typedef struct { \
720 int _static_assert[(x) ? 0 : -1]; \
721 } _static_assert_ ## line __attribute__((unavailable))
722 #endif
723
724
725 /***********************************************************************
726 * object_getClass.
727 * Locking: None. If you add locking, tell gdb (rdar://7516456).
728 **********************************************************************/
729 static inline Class _object_getClass(id obj)
730 {
731 #if SUPPORT_TAGGED_POINTERS
732 if (OBJC_IS_TAGGED_PTR(obj)) {
733 uint8_t slotNumber = ((uint8_t) (uint64_t) obj) & 0x0F;
734 Class isa = _objc_tagged_isa_table[slotNumber];
735 return isa;
736 }
737 #endif
738 if (obj) return obj->isa;
739 else return Nil;
740 }
741
742
743 // Global operator new and delete. We must not use any app overrides.
744 // This ALSO REQUIRES each of these be in libobjc's unexported symbol list.
745 #if __cplusplus
746 #import <new>
747 inline void* operator new(std::size_t size) throw (std::bad_alloc) { return _malloc_internal(size); }
748 inline void* operator new[](std::size_t size) throw (std::bad_alloc) { return _malloc_internal(size); }
749 inline void* operator new(std::size_t size, const std::nothrow_t&) throw() { return _malloc_internal(size); }
750 inline void* operator new[](std::size_t size, const std::nothrow_t&) throw() { return _malloc_internal(size); }
751 inline void operator delete(void* p) throw() { _free_internal(p); }
752 inline void operator delete[](void* p) throw() { _free_internal(p); }
753 inline void operator delete(void* p, const std::nothrow_t&) throw() { _free_internal(p); }
754 inline void operator delete[](void* p, const std::nothrow_t&) throw() { _free_internal(p); }
755 #endif
756
757
758 #endif /* _OBJC_PRIVATE_H_ */
759