]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-private.h
objc4-493.11.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-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 extern bool noSideTableLocksHeld(void);
363
364 #define rwlock_unlock(m, s) \
365 do { \
366 if ((s) == RDONLY) rwlock_unlock_read(m); \
367 else if ((s) == RDWR) rwlock_unlock_write(m); \
368 } while (0)
369
370
371 extern NXHashTable *class_hash;
372
373 #if !TARGET_OS_WIN32
374 /* nil handler object */
375 extern id _objc_nilReceiver;
376 extern id _objc_setNilReceiver(id newNilReceiver);
377 extern id _objc_getNilReceiver(void);
378 #endif
379
380 /* forward handler functions */
381 extern void *_objc_forward_handler;
382 extern void *_objc_forward_stret_handler;
383
384 /* tagged pointer support */
385 #if SUPPORT_TAGGED_POINTERS
386
387 #define OBJC_IS_TAGGED_PTR(PTR) ((uintptr_t)(PTR) & 0x1)
388 extern Class _objc_tagged_isa_table[16];
389
390 #else
391
392 #define OBJC_IS_TAGGED_PTR(PTR) 0
393
394 #endif
395
396
397 /* ignored selector support */
398
399 /* Non-GC: no ignored selectors
400 GC without fixup dispatch: some selectors ignored, remapped to kIgnore
401 GC with fixup dispatch: some selectors ignored, but not remapped
402 */
403
404 static inline int ignoreSelector(SEL sel)
405 {
406 #if !SUPPORT_GC
407 return NO;
408 #elif SUPPORT_IGNORED_SELECTOR_CONSTANT
409 return UseGC && sel == (SEL)kIgnore;
410 #else
411 return UseGC &&
412 (sel == @selector(retain) ||
413 sel == @selector(release) ||
414 sel == @selector(autorelease) ||
415 sel == @selector(retainCount) ||
416 sel == @selector(dealloc));
417 #endif
418 }
419
420 static inline int ignoreSelectorNamed(const char *sel)
421 {
422 #if !SUPPORT_GC
423 return NO;
424 #else
425 // release retain retainCount dealloc autorelease
426 return (UseGC &&
427 ( (sel[0] == 'r' && sel[1] == 'e' &&
428 (strcmp(&sel[2], "lease") == 0 ||
429 strcmp(&sel[2], "tain") == 0 ||
430 strcmp(&sel[2], "tainCount") == 0 ))
431 ||
432 (strcmp(sel, "dealloc") == 0)
433 ||
434 (sel[0] == 'a' && sel[1] == 'u' &&
435 strcmp(&sel[2], "torelease") == 0)));
436 #endif
437 }
438
439 /* Protocol implementation */
440 #if !__OBJC2__
441 struct old_protocol;
442 PRIVATE_EXTERN struct objc_method_description * lookup_protocol_method(struct old_protocol *proto, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod);
443 #else
444 PRIVATE_EXTERN Method _protocol_getMethod(Protocol *p, SEL sel, BOOL isRequiredMethod, BOOL isInstanceMethod);
445 #endif
446
447 /* GC and RTP startup */
448 extern void gc_init(BOOL wantsGC, BOOL wantsCompaction);
449 extern void rtp_init(void);
450
451 /* Exceptions */
452 struct alt_handler_list;
453 extern void exception_init(void);
454 extern void _destroyAltHandlerList(struct alt_handler_list *list);
455
456 /* Class change notifications (gdb only for now) */
457 #define OBJC_CLASS_ADDED (1<<0)
458 #define OBJC_CLASS_REMOVED (1<<1)
459 #define OBJC_CLASS_IVARS_CHANGED (1<<2)
460 #define OBJC_CLASS_METHODS_CHANGED (1<<3)
461 extern void gdb_objc_class_changed(Class cls, unsigned long changes, const char *classname)
462 __attribute__((noinline));
463
464 /* Write barrier implementations */
465 extern id objc_assign_strongCast_non_gc(id value, id *dest);
466 extern id objc_assign_global_non_gc(id value, id *dest);
467 extern id objc_assign_threadlocal_non_gc(id value, id *dest);
468 extern id objc_assign_ivar_non_gc(id value, id dest, ptrdiff_t offset);
469 extern id objc_assign_strongCast_gc(id val, id *dest);
470 extern id objc_assign_global_gc(id val, id *dest);
471 extern id objc_assign_threadlocal_gc(id val, id *dest);
472 extern id objc_assign_ivar_gc(id value, id dest, ptrdiff_t offset);
473
474 extern id objc_getAssociatedObject_non_gc(id object, const void *key);
475 extern void objc_setAssociatedObject_non_gc(id object, const void *key, id value, objc_AssociationPolicy policy);
476 extern id objc_getAssociatedObject_gc(id object, const void *key);
477 extern void objc_setAssociatedObject_gc(id object, const void *key, id value, objc_AssociationPolicy policy);
478
479 #if SUPPORT_GC
480
481 /* GC weak reference fixup. */
482 extern void gc_fixup_weakreferences(id newObject, id oldObject);
483
484 /* GC datasegment registration. */
485 extern void gc_register_datasegment(uintptr_t base, size_t size);
486 extern void gc_unregister_datasegment(uintptr_t base, size_t size);
487 extern void gc_fixup_barrier_stubs(const struct dyld_image_info *info);
488
489 /* objc_dumpHeap implementation */
490 extern BOOL _objc_dumpHeap(auto_zone_t *zone, const char *filename);
491
492 /*
493 objc_assign_ivar, objc_assign_global, objc_assign_threadlocal, and objc_assign_strongCast MUST NOT be called directly
494 from inside libobjc. They live in the data segment, and must be called through the
495 following pointer(s) for libobjc to exist in the shared cache.
496
497 Note: If we build with GC enabled, gcc will emit calls to the original functions, which will break this.
498 */
499
500 extern id (*objc_assign_ivar_internal)(id, id, ptrdiff_t);
501
502 #endif
503
504 /* Code modification */
505 extern size_t objc_branch_size(void *entry, void *target);
506 extern size_t objc_write_branch(void *entry, void *target);
507 extern size_t objc_cond_branch_size(void *entry, void *target, unsigned cond);
508 extern size_t objc_write_cond_branch(void *entry, void *target, unsigned cond);
509 #if defined(__i386__) || defined(__x86_64__)
510 #define COND_ALWAYS 0xE9 /* JMP rel32 */
511 #define COND_NE 0x85 /* JNE rel32 (0F 85) */
512 #endif
513
514
515 // Settings from environment variables
516 #if !SUPPORT_ENVIRON
517 # define ENV(x) enum { x = 0 }
518 #else
519 # define ENV(x) extern int x
520 #endif
521 ENV(PrintImages); // env OBJC_PRINT_IMAGES
522 ENV(PrintLoading); // env OBJC_PRINT_LOAD_METHODS
523 ENV(PrintInitializing); // env OBJC_PRINT_INITIALIZE_METHODS
524 ENV(PrintResolving); // env OBJC_PRINT_RESOLVED_METHODS
525 ENV(PrintConnecting); // env OBJC_PRINT_CLASS_SETUP
526 ENV(PrintProtocols); // env OBJC_PRINT_PROTOCOL_SETUP
527 ENV(PrintIvars); // env OBJC_PRINT_IVAR_SETUP
528 ENV(PrintVtables); // env OBJC_PRINT_VTABLE_SETUP
529 ENV(PrintVtableImages); // env OBJC_PRINT_VTABLE_IMAGES
530 ENV(PrintFuture); // env OBJC_PRINT_FUTURE_CLASSES
531 ENV(PrintRTP); // env OBJC_PRINT_RTP
532 ENV(PrintGC); // env OBJC_PRINT_GC
533 ENV(PrintPreopt); // env OBJC_PRINT_PREOPTIMIZATION
534 ENV(PrintCxxCtors); // env OBJC_PRINT_CXX_CTORS
535 ENV(PrintExceptions); // env OBJC_PRINT_EXCEPTIONS
536 ENV(PrintExceptionThrow); // env OBJC_PRINT_EXCEPTION_THROW
537 ENV(PrintAltHandlers); // env OBJC_PRINT_ALT_HANDLERS
538 ENV(PrintDeprecation); // env OBJC_PRINT_DEPRECATION_WARNINGS
539 ENV(PrintReplacedMethods); // env OBJC_PRINT_REPLACED_METHODS
540 ENV(PrintCaches); // env OBJC_PRINT_CACHE_SETUP
541 ENV(PrintPoolHiwat); // env OBJC_PRINT_POOL_HIGHWATER
542 ENV(UseInternalZone); // env OBJC_USE_INTERNAL_ZONE
543
544 ENV(DebugUnload); // env OBJC_DEBUG_UNLOAD
545 ENV(DebugFragileSuperclasses); // env OBJC_DEBUG_FRAGILE_SUPERCLASSES
546 ENV(DebugFinalizers); // env OBJC_DEBUG_FINALIZERS
547 ENV(DebugNilSync); // env OBJC_DEBUG_NIL_SYNC
548 ENV(DebugNonFragileIvars); // env OBJC_DEBUG_NONFRAGILE_IVARS
549 ENV(DebugAltHandlers); // env OBJC_DEBUG_ALT_HANDLERS
550
551 ENV(DisableGC); // env OBJC_DISABLE_GC
552 ENV(DisableVtables); // env OBJC_DISABLE_VTABLES
553 ENV(DisablePreopt); // env OBJC_DISABLE_PREOPTIMIZATION
554
555 #undef ENV
556
557 extern void environ_init(void);
558
559 extern void logReplacedMethod(const char *className, SEL s, BOOL isMeta, const char *catName, IMP oldImp, IMP newImp);
560
561 static __inline uint32_t _objc_strhash(const char *s) {
562 uint32_t hash = 0;
563 for (;;) {
564 int a = *s++;
565 if (0 == a) break;
566 hash += (hash << 8) + a;
567 }
568 return hash;
569 }
570
571
572 // objc per-thread storage
573 typedef struct {
574 struct _objc_initializing_classes *initializingClasses; // for +initialize
575 struct SyncCache *syncCache; // for @synchronize
576 struct alt_handler_list *handlerList; // for exception alt handlers
577
578 // If you add new fields here, don't forget to update
579 // _objc_pthread_destroyspecific()
580
581 } _objc_pthread_data;
582
583 extern _objc_pthread_data *_objc_fetch_pthread_data(BOOL create);
584 extern void tls_init(void);
585
586
587 // cache.h
588 #if TARGET_OS_WIN32
589
590 #else
591 static inline int isPowerOf2(unsigned long l) { return 1 == __builtin_popcountl(l); }
592 #endif
593 extern void flush_caches(Class cls, BOOL flush_meta);
594 extern void flush_cache(Class cls);
595 extern BOOL _cache_fill(Class cls, Method smt, SEL sel);
596 extern void _cache_addForwardEntry(Class cls, SEL sel);
597 extern IMP _cache_addIgnoredEntry(Class cls, SEL sel);
598 extern void _cache_free(Cache cache);
599 extern void _cache_collect(bool collectALot);
600
601 extern mutex_t cacheUpdateLock;
602
603 // encoding.h
604 extern unsigned int encoding_getNumberOfArguments(const char *typedesc);
605 extern unsigned int encoding_getSizeOfArguments(const char *typedesc);
606 extern unsigned int encoding_getArgumentInfo(const char *typedesc, int arg, const char **type, int *offset);
607 extern void encoding_getReturnType(const char *t, char *dst, size_t dst_len);
608 extern char * encoding_copyReturnType(const char *t);
609 extern void encoding_getArgumentType(const char *t, unsigned int index, char *dst, size_t dst_len);
610 extern char *encoding_copyArgumentType(const char *t, unsigned int index);
611
612 // sync.h
613 extern void _destroySyncCache(struct SyncCache *cache);
614
615 // arr
616 extern void (^objc_arr_log)(const char *, id param);
617 extern void arr_init(void);
618 extern id objc_autoreleaseReturnValue(id obj);
619
620
621 // layout.h
622 typedef struct {
623 uint8_t *bits;
624 size_t bitCount;
625 size_t bitsAllocated;
626 BOOL weak;
627 } layout_bitmap;
628 extern layout_bitmap layout_bitmap_create(const unsigned char *layout_string, size_t layoutStringInstanceSize, size_t instanceSize, BOOL weak);
629 extern layout_bitmap layout_bitmap_create_empty(size_t instanceSize, BOOL weak);
630 extern void layout_bitmap_free(layout_bitmap bits);
631 extern const unsigned char *layout_string_create(layout_bitmap bits);
632 extern void layout_bitmap_set_ivar(layout_bitmap bits, const char *type, size_t offset);
633 extern void layout_bitmap_grow(layout_bitmap *bits, size_t newCount);
634 extern void layout_bitmap_slide(layout_bitmap *bits, size_t oldPos, size_t newPos);
635 extern void layout_bitmap_slide_anywhere(layout_bitmap *bits, size_t oldPos, size_t newPos);
636 extern BOOL layout_bitmap_splat(layout_bitmap dst, layout_bitmap src,
637 size_t oldSrcInstanceSize);
638 extern BOOL layout_bitmap_or(layout_bitmap dst, layout_bitmap src, const char *msg);
639 extern BOOL layout_bitmap_clear(layout_bitmap dst, layout_bitmap src, const char *msg);
640 extern void layout_bitmap_print(layout_bitmap bits);
641
642
643 // fixme runtime
644 extern id look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler);
645 extern const char *map_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
646 extern const char *map_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
647 extern const char * load_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
648 extern BOOL load_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
649 extern void unmap_image(const struct mach_header *mh, intptr_t vmaddr_slide);
650 extern void unmap_image_nolock(const struct mach_header *mh);
651 extern void _read_images(header_info **hList, uint32_t hCount);
652 extern void prepare_load_methods(header_info *hi);
653 extern void _unload_image(header_info *hi);
654 extern const char ** _objc_copyClassNamesForImage(header_info *hi, unsigned int *outCount);
655
656 extern Class _objc_allocateFutureClass(const char *name);
657
658
659 extern const header_info *_headerForClass(Class cls);
660
661 extern Class _class_getSuperclass(Class cls);
662 extern BOOL _class_getInfo(Class cls, int info);
663 extern const char *_class_getName(Class cls);
664 extern size_t _class_getInstanceSize(Class cls);
665 extern Class _class_getMeta(Class cls);
666 extern BOOL _class_isMetaClass(Class cls);
667 extern Cache _class_getCache(Class cls);
668 extern void _class_setCache(Class cls, Cache cache);
669 extern BOOL _class_isInitializing(Class cls);
670 extern BOOL _class_isInitialized(Class cls);
671 extern void _class_setInitializing(Class cls);
672 extern void _class_setInitialized(Class cls);
673 extern Class _class_getNonMetaClass(Class cls);
674 extern Method _class_getMethod(Class cls, SEL sel);
675 extern Method _class_getMethodNoSuper(Class cls, SEL sel);
676 extern Method _class_getMethodNoSuper_nolock(Class cls, SEL sel);
677 extern BOOL _class_isLoadable(Class cls);
678 extern IMP _class_getLoadMethod(Class cls);
679 extern BOOL _class_hasLoadMethod(Class cls);
680 extern BOOL _class_hasCxxStructors(Class cls);
681 extern BOOL _class_shouldFinalizeOnMainThread(Class cls);
682 extern void _class_setFinalizeOnMainThread(Class cls);
683 extern BOOL _class_instancesHaveAssociatedObjects(Class cls);
684 extern void _class_setInstancesHaveAssociatedObjects(Class cls);
685 extern BOOL _class_shouldGrowCache(Class cls);
686 extern void _class_setGrowCache(Class cls, BOOL grow);
687 extern Ivar _class_getVariable(Class cls, const char *name, Class *memberOf);
688 extern BOOL _class_usesAutomaticRetainRelease(Class cls);
689 extern uint32_t _class_getInstanceStart(Class cls);
690
691 extern unsigned _class_createInstancesFromZone(Class cls, size_t extraBytes, void *zone, id *results, unsigned num_requested);
692 extern id _objc_constructOrFree(Class cls, void *bytes);
693
694 extern const char *_category_getName(Category cat);
695 extern const char *_category_getClassName(Category cat);
696 extern Class _category_getClass(Category cat);
697 extern IMP _category_getLoadMethod(Category cat);
698
699 extern BOOL object_cxxConstruct(id obj);
700 extern void object_cxxDestruct(id obj);
701
702 extern Method _class_resolveMethod(Class cls, SEL sel);
703 extern void log_and_fill_cache(Class cls, Class implementer, Method meth, SEL sel);
704
705 #define OBJC_WARN_DEPRECATED \
706 do { \
707 static int warned = 0; \
708 if (!warned) { \
709 warned = 1; \
710 _objc_inform_deprecated(__FUNCTION__, NULL); \
711 } \
712 } while (0) \
713
714 __END_DECLS
715
716
717 #ifndef STATIC_ASSERT
718 # define STATIC_ASSERT(x) _STATIC_ASSERT2(x, __LINE__)
719 # define _STATIC_ASSERT2(x, line) _STATIC_ASSERT3(x, line)
720 # define _STATIC_ASSERT3(x, line) \
721 typedef struct { \
722 int _static_assert[(x) ? 0 : -1]; \
723 } _static_assert_ ## line __attribute__((unavailable))
724 #endif
725
726
727 /***********************************************************************
728 * object_getClass.
729 * Locking: None. If you add locking, tell gdb (rdar://7516456).
730 **********************************************************************/
731 static inline Class _object_getClass(id obj)
732 {
733 #if SUPPORT_TAGGED_POINTERS
734 if (OBJC_IS_TAGGED_PTR(obj)) {
735 uint8_t slotNumber = ((uint8_t) (uint64_t) obj) & 0x0F;
736 Class isa = _objc_tagged_isa_table[slotNumber];
737 return isa;
738 }
739 #endif
740 if (obj) return obj->isa;
741 else return Nil;
742 }
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 #import <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