]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-private.h
objc4-437.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-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-rtp.h"
40 #include "objc-references.h"
41 #include "objc-initialize.h"
42 #include "objc-loadmethod.h"
43 #include "objc-internal.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 #if defined(OBJC_NO_GC) != defined(NO_GC)
58 # error OBJC_NO_GC and NO_GC inconsistent
59 #endif
60
61 #ifndef NO_GC
62 # include <auto_zone.h>
63 extern BOOL UseGC; // equivalent to calling objc_collecting_enabled()
64 extern auto_zone_t *gc_zone; // the GC zone, or NULL if no GC
65 extern void objc_addRegisteredClass(Class c);
66 extern void objc_removeRegisteredClass(Class c);
67 #else
68 # define UseGC NO
69 # define gc_zone NULL
70 # define objc_assign_ivar_internal objc_assign_ivar
71 # define objc_addRegisteredClass(c) do {} while(0)
72 # define objc_removeRegisteredClass(c) do {} while(0)
73 /* Uses of the following must be protected with UseGC. */
74 extern id gc_unsupported_dont_call();
75 # define auto_zone_allocate_object gc_unsupported_dont_call
76 # define auto_zone_retain gc_unsupported_dont_call
77 # define auto_zone_release gc_unsupported_dont_call
78 # define auto_zone_is_valid_pointer gc_unsupported_dont_call
79 # define auto_zone_write_barrier_memmove gc_unsupported_dont_call
80 # define AUTO_OBJECT_SCANNED 0
81 #endif
82
83 struct old_category;
84 struct old_method_list;
85 typedef struct {
86 IMP imp;
87 SEL sel;
88 } message_ref;
89
90 #if __OBJC2__
91
92 typedef struct objc_module *Module;
93 typedef struct objc_cache *Cache;
94
95 #endif
96
97
98 #if OLD
99
100 struct old_class {
101 struct old_class *isa;
102 struct old_class *super_class;
103 const char *name;
104 long version;
105 long info;
106 long instance_size;
107 struct old_ivar_list *ivars;
108 struct old_method_list **methodLists;
109 Cache cache;
110 struct old_protocol_list *protocols;
111 // CLS_EXT only
112 const char *ivar_layout;
113 struct old_class_ext *ext;
114 };
115
116 struct old_class_ext {
117 uint32_t size;
118 const char *weak_ivar_layout;
119 struct objc_property_list **propertyLists;
120 };
121
122 struct old_category {
123 char *category_name;
124 char *class_name;
125 struct old_method_list *instance_methods;
126 struct old_method_list *class_methods;
127 struct old_protocol_list *protocols;
128 uint32_t size;
129 struct objc_property_list *instance_properties;
130 };
131
132 struct old_ivar {
133 char *ivar_name;
134 char *ivar_type;
135 int ivar_offset;
136 #ifdef __LP64__
137 int space;
138 #endif
139 };
140
141 struct old_ivar_list {
142 int ivar_count;
143 #ifdef __LP64__
144 int space;
145 #endif
146 /* variable length structure */
147 struct old_ivar ivar_list[1];
148 };
149
150
151 struct old_method {
152 SEL method_name;
153 char *method_types;
154 IMP method_imp;
155 };
156
157 struct old_method_list {
158 struct old_method_list *obsolete;
159
160 int method_count;
161 #ifdef __LP64__
162 int space;
163 #endif
164 /* variable length structure */
165 struct old_method method_list[1];
166 };
167
168 struct old_protocol {
169 Class isa;
170 const char *protocol_name;
171 struct old_protocol_list *protocol_list;
172 struct objc_method_description_list *instance_methods;
173 struct objc_method_description_list *class_methods;
174 };
175
176 struct old_protocol_list {
177 struct old_protocol_list *next;
178 long count;
179 struct old_protocol *list[1];
180 };
181
182 struct old_protocol_ext {
183 uint32_t size;
184 struct objc_method_description_list *optional_instance_methods;
185 struct objc_method_description_list *optional_class_methods;
186 struct objc_property_list *instance_properties;
187 };
188
189 #endif
190
191 typedef objc_property_t Property;
192
193 struct objc_property {
194 const char *name;
195 const char *attributes;
196 };
197
198 struct objc_property_list {
199 uint32_t entsize;
200 uint32_t count;
201 struct objc_property first;
202 };
203
204 typedef struct {
205 uint32_t version; // currently 0
206 uint32_t flags;
207 } objc_image_info;
208
209 // masks for objc_image_info.flags
210 #define OBJC_IMAGE_IS_REPLACEMENT (1<<0)
211 #define OBJC_IMAGE_SUPPORTS_GC (1<<1)
212 #define OBJC_IMAGE_REQUIRES_GC (1<<2)
213 #define OBJC_IMAGE_OPTIMIZED_BY_DYLD (1<<3)
214
215
216 #define _objcHeaderIsReplacement(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_IS_REPLACEMENT))
217
218 /* OBJC_IMAGE_IS_REPLACEMENT:
219 Don't load any classes
220 Don't load any categories
221 Do fix up selector refs (@selector points to them)
222 Do fix up class refs (@class and objc_msgSend points to them)
223 Do fix up protocols (@protocol points to them)
224 Do fix up super_class pointers in classes ([super ...] points to them)
225 Future: do load new classes?
226 Future: do load new categories?
227 Future: do insert new methods on existing classes?
228 Future: do insert new methods on existing categories?
229 */
230
231 #define _objcInfoSupportsGC(info) (((info)->flags & OBJC_IMAGE_SUPPORTS_GC) ? 1 : 0)
232 #define _objcInfoRequiresGC(info) (((info)->flags & OBJC_IMAGE_REQUIRES_GC) ? 1 : 0)
233 #define _objcHeaderSupportsGC(h) ((h)->info && _objcInfoSupportsGC((h)->info))
234 #define _objcHeaderRequiresGC(h) ((h)->info && _objcInfoRequiresGC((h)->info))
235
236 /* OBJC_IMAGE_SUPPORTS_GC:
237 was compiled with -fobjc-gc flag, regardless of whether write-barriers were issued
238 if executable image compiled this way, then all subsequent libraries etc. must also be this way
239 */
240
241 #define _objcHeaderOptimizedByDyld(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_OPTIMIZED_BY_DYLD))
242
243 /* OBJC_IMAGE_OPTIMIZED_BY_DYLD:
244 Assorted metadata precooked in the dyld shared cache.
245 Never set for images outside the shared cache file itself.
246 */
247
248
249 typedef struct _header_info {
250 struct _header_info *next;
251 const headerType * mhdr;
252 struct objc_module *mod_ptr;
253 size_t mod_count;
254 const objc_image_info *info;
255 BOOL allClassesRealized;
256 os_header_info os;
257 } header_info;
258
259 extern header_info *FirstHeader;
260 extern header_info *LastHeader;
261 extern int HeaderCount;
262
263 extern void _objc_appendHeader(header_info *hi);
264 extern void _objc_removeHeader(header_info *hi);
265 extern const char *_nameForHeader(const headerType*);
266
267 extern objc_image_info *_getObjcImageInfo(const headerType *head, ptrdiff_t slide, size_t *size);
268 extern const char *_getObjcHeaderName(const headerType *head);
269 extern ptrdiff_t _getImageSlide(const headerType *header);
270
271
272 extern Module _getObjcModules(const header_info *hi, size_t *count);
273 extern SEL *_getObjcSelectorRefs(const header_info *hi, size_t *count);
274 extern BOOL _hasObjcContents(const header_info *hi);
275 #if !__OBJC2__
276 extern struct old_protocol **_getObjcProtocols(const header_info *head, size_t *count);
277 extern struct old_class **_getObjcClassRefs(const header_info *hi, size_t *count);
278 extern const char *_getObjcClassNames(const header_info *hi, size_t *size);
279 #endif
280
281 #if __OBJC2__
282 extern SEL *_getObjc2SelectorRefs(const header_info *hi, size_t *count);
283 extern message_ref *_getObjc2MessageRefs(const header_info *hi, size_t *count);extern struct class_t **_getObjc2ClassRefs(const header_info *hi, size_t *count);
284 extern struct class_t **_getObjc2SuperRefs(const header_info *hi, size_t *count);
285 extern struct class_t **_getObjc2ClassList(const header_info *hi, size_t *count);
286 extern struct class_t **_getObjc2NonlazyClassList(const header_info *hi, size_t *count);
287 extern struct category_t **_getObjc2CategoryList(const header_info *hi, size_t *count);
288 extern struct category_t **_getObjc2NonlazyCategoryList(const header_info *hi, size_t *count);
289 extern struct protocol_t **_getObjc2ProtocolList(const header_info *head, size_t *count);
290 extern struct protocol_t **_getObjc2ProtocolRefs(const header_info *head, size_t *count);
291 #endif
292
293 #define END_OF_METHODS_LIST ((struct old_method_list*)-1)
294
295
296 /* selectors */
297 extern void sel_init(BOOL gc);
298 extern SEL sel_registerNameNoLock(const char *str, BOOL copy);
299 extern void sel_lock(void);
300 extern void sel_unlock(void);
301 extern BOOL sel_preoptimizationValid(const header_info *hi);
302 extern void disableSelectorPreoptimization(void);
303
304 extern SEL SEL_load;
305 extern SEL SEL_initialize;
306 extern SEL SEL_resolveClassMethod;
307 extern SEL SEL_resolveInstanceMethod;
308 extern SEL SEL_cxx_construct;
309 extern SEL SEL_cxx_destruct;
310 extern SEL SEL_retain;
311 extern SEL SEL_release;
312 extern SEL SEL_autorelease;
313 extern SEL SEL_copy;
314 extern SEL SEL_finalize;
315
316
317 /* optional malloc zone for runtime data */
318 extern malloc_zone_t *_objc_internal_zone(void);
319 extern void *_malloc_internal(size_t size);
320 extern void *_calloc_internal(size_t count, size_t size);
321 extern void *_realloc_internal(void *ptr, size_t size);
322 extern char *_strdup_internal(const char *str);
323 extern char *_strdupcat_internal(const char *s1, const char *s2);
324 extern void *_memdup_internal(const void *mem, size_t size);
325 extern void _free_internal(void *ptr);
326
327 extern Class _calloc_class(size_t size);
328
329 #if !__OBJC2__
330 extern Class objc_getOrigClass (const char *name);
331 extern IMP lookupNamedMethodInMethodList(struct old_method_list *mlist, const char *meth_name);
332 extern void _objc_insertMethods(struct old_class *cls, struct old_method_list *mlist, struct old_category *cat);
333 extern void _objc_removeMethods(struct old_class *cls, struct old_method_list *mlist);
334 extern void _objc_flush_caches (Class cls);
335 extern void _class_addProperties(struct old_class *cls, struct objc_property_list *additions);
336 extern void change_class_references(struct old_class *imposter, struct old_class *original, struct old_class *copy, BOOL changeSuperRefs);
337 extern void flush_marked_caches(void);
338 extern void set_superclass(struct old_class *cls, struct old_class *supercls);
339 #endif
340
341 extern IMP lookUpMethod(Class, SEL, BOOL initialize, BOOL cache);
342 extern void lockForMethodLookup(void);
343 extern void unlockForMethodLookup(void);
344 extern IMP prepareForMethodLookup(Class cls, SEL sel, BOOL initialize);
345
346 extern IMP _cache_getImp(Class cls, SEL sel);
347 extern Method _cache_getMethod(Class cls, SEL sel, IMP objc_msgForward_internal_imp);
348
349 /* message dispatcher */
350 extern IMP _class_lookupMethodAndLoadCache(Class, SEL);
351 extern id _objc_msgForward_internal(id self, SEL sel, ...);
352 extern id _objc_ignored_method(id self, SEL _cmd);
353
354 /* errors */
355 extern void __objc_error(id, const char *, ...) __attribute__((format (printf, 2, 3)));
356 extern void _objc_inform(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
357 extern void _objc_inform_on_crash(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
358 extern void _objc_inform_now_and_on_crash(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
359 extern void _objc_warn_deprecated(const char *oldname, const char *newname) __attribute__((noinline));
360 extern void _objc_error(id, const char *, va_list);
361 extern void inform_duplicate(const char *name, Class oldCls, Class cls);
362
363 /* magic */
364 extern Class _objc_getFreedObjectClass (void);
365 #ifndef OBJC_INSTRUMENTED
366 extern const struct objc_cache _objc_empty_cache;
367 #else
368 extern struct objc_cache _objc_empty_cache;
369 #endif
370 #if __OBJC2__
371 extern IMP _objc_empty_vtable[128];
372 #endif
373
374 /* map table additions */
375 extern void *NXMapKeyCopyingInsert(NXMapTable *table, const void *key, const void *value);
376 extern void *NXMapKeyFreeingRemove(NXMapTable *table, const void *key);
377
378 /* locking */
379 /* Every lock used anywhere must be declared here.
380 * Locks not declared here may cause gdb deadlocks. */
381 extern void lock_init(void);
382 extern rwlock_t selLock;
383 extern mutex_t cacheUpdateLock;
384 extern recursive_mutex_t loadMethodLock;
385 #if __OBJC2__
386 extern rwlock_t runtimeLock;
387 #else
388 extern mutex_t classLock;
389 extern mutex_t methodListLock;
390 #endif
391
392 /* Debugger mode for gdb */
393 #define DEBUGGER_OFF 0
394 #define DEBUGGER_PARTIAL 1
395 #define DEBUGGER_FULL 2
396 extern int startDebuggerMode(void);
397 extern void endDebuggerMode(void);
398
399 #if defined(NDEBUG) || TARGET_OS_WIN32
400
401 #define _destroyLockList(x) do { } while (0)
402
403 #define mutex_lock(m) _mutex_lock_nodebug(m)
404 #define mutex_try_lock(m) _mutex_try_lock_nodebug(m)
405 #define mutex_unlock(m) _mutex_unlock_nodebug(m)
406 #define mutex_assert_locked(m) do { } while (0)
407 #define mutex_assert_unlocked(m) do { } while (0)
408
409 #define recursive_mutex_lock(m) _recursive_mutex_lock_nodebug(m)
410 #define recursive_mutex_try_lock(m) _recursive_mutex_try_lock_nodebug(m)
411 #define recursive_mutex_unlock(m) _recursive_mutex_unlock_nodebug(m)
412 #define recursive_mutex_assert_locked(m) do { } while (0)
413 #define recursive_mutex_assert_unlocked(m) do { } while (0)
414
415 #define monitor_enter(m) _monitor_enter_nodebug(m)
416 #define monitor_exit(m) _monitor_exit_nodebug(m)
417 #define monitor_wait(m) _monitor_wait_nodebug(m)
418 #define monitor_assert_locked(m) do { } while (0)
419 #define monitor_assert_unlocked(m) do { } while (0)
420
421 #define rwlock_read(m) _rwlock_read_nodebug(m)
422 #define rwlock_write(m) _rwlock_write_nodebug(m)
423 #define rwlock_try_read(m) _rwlock_try_read_nodebug(m)
424 #define rwlock_try_write(m) _rwlock_try_write_nodebug(m)
425 #define rwlock_unlock_read(m) _rwlock_unlock_read_nodebug(m)
426 #define rwlock_unlock_write(m) _rwlock_unlock_write_nodebug(m)
427 #define rwlock_assert_reading(m) do { } while (0)
428 #define rwlock_assert_writing(m) do { } while (0)
429 #define rwlock_assert_locked(m) do { } while (0)
430 #define rwlock_assert_unlocked(m) do { } while (0)
431
432 #else
433
434 struct _objc_lock_list;
435 extern void _destroyLockList(struct _objc_lock_list *locks);
436
437 extern int _mutex_lock_debug(mutex_t *lock, const char *name);
438 extern int _mutex_try_lock_debug(mutex_t *lock, const char *name);
439 extern int _mutex_unlock_debug(mutex_t *lock, const char *name);
440 extern void _mutex_assert_locked_debug(mutex_t *lock, const char *name);
441 extern void _mutex_assert_unlocked_debug(mutex_t *lock, const char *name);
442
443 extern int _recursive_mutex_lock_debug(recursive_mutex_t *lock, const char *name);
444 extern int _recursive_mutex_try_lock_debug(recursive_mutex_t *lock, const char *name);
445 extern int _recursive_mutex_unlock_debug(recursive_mutex_t *lock, const char *name);
446 extern void _recursive_mutex_assert_locked_debug(recursive_mutex_t *lock, const char *name);
447 extern void _recursive_mutex_assert_unlocked_debug(recursive_mutex_t *lock, const char *name);
448
449 extern int _monitor_enter_debug(monitor_t *lock, const char *name);
450 extern int _monitor_exit_debug(monitor_t *lock, const char *name);
451 extern int _monitor_wait_debug(monitor_t *lock, const char *name);
452 extern void _monitor_assert_locked_debug(monitor_t *lock, const char *name);
453 extern void _monitor_assert_unlocked_debug(monitor_t *lock, const char *name);
454
455 extern void _rwlock_read_debug(rwlock_t *l, const char *name);
456 extern void _rwlock_write_debug(rwlock_t *l, const char *name);
457 extern int _rwlock_try_read_debug(rwlock_t *l, const char *name);
458 extern int _rwlock_try_write_debug(rwlock_t *l, const char *name);
459 extern void _rwlock_unlock_read_debug(rwlock_t *l, const char *name);
460 extern void _rwlock_unlock_write_debug(rwlock_t *l, const char *name);
461 extern void _rwlock_assert_reading_debug(rwlock_t *l, const char *name);
462 extern void _rwlock_assert_writing_debug(rwlock_t *l, const char *name);
463 extern void _rwlock_assert_locked_debug(rwlock_t *l, const char *name);
464 extern void _rwlock_assert_unlocked_debug(rwlock_t *l, const char *name);
465
466 #define mutex_lock(m) _mutex_lock_debug (m, #m)
467 #define mutex_try_lock(m) _mutex_try_lock_debug (m, #m)
468 #define mutex_unlock(m) _mutex_unlock_debug (m, #m)
469 #define mutex_assert_locked(m) _mutex_assert_locked_debug (m, #m)
470 #define mutex_assert_unlocked(m) _mutex_assert_unlocked_debug (m, #m)
471
472 #define recursive_mutex_lock(m) _recursive_mutex_lock_debug (m, #m)
473 #define recursive_mutex_try_lock(m) _recursive_mutex_try_lock_debug (m, #m)
474 #define recursive_mutex_unlock(m) _recursive_mutex_unlock_debug (m, #m)
475 #define recursive_mutex_assert_locked(m) _recursive_mutex_assert_locked_debug (m, #m)
476 #define recursive_mutex_assert_unlocked(m) _recursive_mutex_assert_unlocked_debug (m, #m)
477
478 #define monitor_enter(m) _monitor_enter_debug(m, #m)
479 #define monitor_exit(m) _monitor_exit_debug(m, #m)
480 #define monitor_wait(m) _monitor_wait_debug(m, #m)
481 #define monitor_assert_locked(m) _monitor_assert_locked_debug(m, #m)
482 #define monitor_assert_unlocked(m) _monitor_assert_unlocked_debug(m, #m)
483
484 #define rwlock_read(m) _rwlock_read_debug(m, #m)
485 #define rwlock_write(m) _rwlock_write_debug(m, #m)
486 #define rwlock_try_read(m) _rwlock_try_read_debug(m, #m)
487 #define rwlock_try_write(m) _rwlock_try_write_debug(m, #m)
488 #define rwlock_unlock_read(m) _rwlock_unlock_read_debug(m, #m)
489 #define rwlock_unlock_write(m) _rwlock_unlock_write_debug(m, #m)
490 #define rwlock_assert_reading(m) _rwlock_assert_reading_debug(m, #m)
491 #define rwlock_assert_writing(m) _rwlock_assert_writing_debug(m, #m)
492 #define rwlock_assert_locked(m) _rwlock_assert_locked_debug(m, #m)
493 #define rwlock_assert_unlocked(m) _rwlock_assert_unlocked_debug(m, #m)
494
495 #endif
496
497 #define rwlock_unlock(m, s) \
498 do { \
499 if ((s) == RDONLY) rwlock_unlock_read(m); \
500 else if ((s) == RDWR) rwlock_unlock_write(m); \
501 } while (0)
502
503
504 extern NXHashTable *class_hash;
505
506 #if !TARGET_OS_WIN32
507 /* nil handler object */
508 extern id _objc_nilReceiver;
509 extern id _objc_setNilReceiver(id newNilReceiver);
510 extern id _objc_getNilReceiver(void);
511 #endif
512
513 /* forward handler functions */
514 extern void *_objc_forward_handler;
515 extern void *_objc_forward_stret_handler;
516
517 /* GC and RTP startup */
518 extern void gc_init(BOOL on);
519 extern void rtp_init(void);
520
521 /* Exceptions */
522 struct alt_handler_list;
523 extern void exception_init(void);
524 extern void _destroyAltHandlerList(struct alt_handler_list *list);
525
526 /* Class change notifications (gdb only for now) */
527 #define OBJC_CLASS_ADDED (1<<0)
528 #define OBJC_CLASS_REMOVED (1<<1)
529 #define OBJC_CLASS_IVARS_CHANGED (1<<2)
530 #define OBJC_CLASS_METHODS_CHANGED (1<<3)
531 extern void gdb_objc_class_changed(Class cls, unsigned long changes, const char *classname)
532 __attribute__((noinline));
533
534 /* Write barrier implementations */
535 extern id objc_assign_strongCast_non_gc(id value, id *dest);
536 extern id objc_assign_global_non_gc(id value, id *dest);
537 extern id objc_assign_ivar_non_gc(id value, id dest, ptrdiff_t offset);
538 extern id objc_assign_strongCast_gc(id val, id *dest);
539 extern id objc_assign_global_gc(id val, id *dest);
540 extern id objc_assign_ivar_gc(id value, id dest, ptrdiff_t offset);
541
542 #ifndef NO_GC
543
544 /* GC weak reference fixup. */
545 extern void gc_fixup_weakreferences(id newObject, id oldObject);
546
547 /* GC datasegment registration. */
548 extern void gc_register_datasegment(uintptr_t base, size_t size);
549 extern void gc_unregister_datasegment(uintptr_t base, size_t size);
550
551 /*
552 objc_assign_ivar, objc_assign_global, and objc_assign_strongCast MUST NOT be called directly
553 from inside libobjc. They live in the data segment, and must be called through the
554 following pointer(s) for libobjc to exist in the shared cache.
555
556 Note: If we build with GC enabled, gcc will emit calls to the original functions, which will break this.
557 */
558
559 extern id (*objc_assign_ivar_internal)(id, id, ptrdiff_t);
560
561 #endif
562
563 /* Code modification */
564 extern size_t objc_branch_size(void *entry, void *target);
565 extern size_t objc_write_branch(void *entry, void *target);
566 extern size_t objc_cond_branch_size(void *entry, void *target, unsigned cond);
567 extern size_t objc_write_cond_branch(void *entry, void *target, unsigned cond);
568 #if defined(__ppc__) || defined(__ppc64__)
569 #define COND_ALWAYS 0x02800000 /* BO=10100, BI=00000 */
570 #define COND_NE 0x00820000 /* BO=00100, BI=00010 */
571 #elif defined(__i386__) || defined(__x86_64__)
572 #define COND_ALWAYS 0xE9 /* JMP rel32 */
573 #define COND_NE 0x85 /* JNE rel32 (0F 85) */
574 #endif
575
576
577 /* Thread-safe info field */
578 #if !__OBJC2__
579 extern void _class_setInfo(Class cls, long set);
580 extern void _class_clearInfo(Class cls, long clear);
581 extern void _class_changeInfo(Class cls, long set, long clear);
582 #endif
583
584
585 #if !defined(SEG_OBJC)
586 #define SEG_OBJC "__OBJC" /* objective-C runtime segment */
587 #endif
588
589
590 // Settings from environment variables
591 #if NO_ENVIRON
592 # define ENV(x) enum { x = 0 }
593 #else
594 # define ENV(x) extern int x
595 #endif
596 ENV(PrintImages); // env OBJC_PRINT_IMAGES
597 ENV(PrintLoading); // env OBJC_PRINT_LOAD_METHODS
598 ENV(PrintInitializing); // env OBJC_PRINT_INITIALIZE_METHODS
599 ENV(PrintResolving); // env OBJC_PRINT_RESOLVED_METHODS
600 ENV(PrintConnecting); // env OBJC_PRINT_CLASS_SETUP
601 ENV(PrintProtocols); // env OBJC_PRINT_PROTOCOL_SETUP
602 ENV(PrintIvars); // env OBJC_PRINT_IVAR_SETUP
603 ENV(PrintVtables); // env OBJC_PRINT_VTABLE_SETUP
604 ENV(PrintVtableImages); // env OBJC_PRINT_VTABLE_IMAGES
605 ENV(PrintFuture); // env OBJC_PRINT_FUTURE_CLASSES
606 ENV(PrintRTP); // env OBJC_PRINT_RTP
607 ENV(PrintGC); // env OBJC_PRINT_GC
608 ENV(PrintPreopt); // env OBJC_PRINT_PREOPTIMIZATION
609 ENV(PrintCxxCtors); // env OBJC_PRINT_CXX_CTORS
610 ENV(PrintExceptions); // env OBJC_PRINT_EXCEPTIONS
611 ENV(PrintAltHandlers); // env OBJC_PRINT_ALT_HANDLERS
612 ENV(PrintDeprecation); // env OBJC_PRINT_DEPRECATION_WARNINGS
613 ENV(PrintReplacedMethods); // env OBJC_PRINT_REPLACED_METHODS
614 ENV(PrintCaches); // env OBJC_PRINT_CACHE_SETUP
615 ENV(UseInternalZone); // env OBJC_USE_INTERNAL_ZONE
616
617 ENV(DebugUnload); // env OBJC_DEBUG_UNLOAD
618 ENV(DebugFragileSuperclasses); // env OBJC_DEBUG_FRAGILE_SUPERCLASSES
619 ENV(DebugFinalizers); // env OBJC_DEBUG_FINALIZERS
620 ENV(DebugNilSync); // env OBJC_DEBUG_NIL_SYNC
621
622 ENV(DisableGC); // env OBJC_DISABLE_GC
623 ENV(DisableVtables); // env OBJC_DISABLE_VTABLES
624 ENV(DisablePreopt); // env OBJC_DISABLE_PREOPTIMIZATION
625 #undef ENV
626
627 extern void environ_init(void);
628
629 extern void logReplacedMethod(const char *className, SEL s, BOOL isMeta, const char *catName, IMP oldImp, IMP newImp);
630
631
632 static __inline int _objc_strcmp(const char *s1, const char *s2) {
633 char c1, c2;
634 for ( ; (c1 = *s1) == (c2 = *s2); s1++, s2++)
635 if (c1 == '\0')
636 return 0;
637 return (c1 - c2);
638 }
639
640 static __inline uint32_t _objc_strhash(const char *s) {
641 uint32_t hash = 0;
642 for (;;) {
643 int a = *s++;
644 if (0 == a) break;
645 hash += (hash << 8) + a;
646 }
647 return hash;
648 }
649
650
651 // objc per-thread storage
652 typedef struct {
653 struct _objc_initializing_classes *initializingClasses; // for +initialize
654 struct _objc_lock_list *lockList; // for lock debugging
655 struct SyncCache *syncCache; // for @synchronize
656 struct alt_handler_list *handlerList; // for exception alt handlers
657
658 // If you add new fields here, don't forget to update
659 // _objc_pthread_destroyspecific()
660
661 } _objc_pthread_data;
662
663 extern _objc_pthread_data *_objc_fetch_pthread_data(BOOL create);
664 extern void tls_init(void);
665
666
667 // Class state
668 #if !__OBJC2__
669 #define ISCLASS(cls) (((cls)->info & CLS_CLASS) != 0)
670 #define ISMETA(cls) (((cls)->info & CLS_META) != 0)
671 #define GETMETA(cls) (ISMETA(cls) ? (cls) : (cls)->isa)
672 #endif
673
674
675 // Attribute for global variables to keep them out of bss storage
676 // To save one page per non-Objective-C process, variables used in
677 // the "Objective-C not used" case should not be in bss storage.
678 // On Tiger, this reduces the number of touched pages for each
679 // CoreFoundation-only process from three to two. See #3857126 and #3857136.
680 #define NOBSS __attribute__((section("__DATA,__data")))
681
682 // cache.h
683 #if TARGET_OS_WIN32
684
685 #else
686 static inline int isPowerOf2(unsigned long l) { return 1 == __builtin_popcountl(l); }
687 #endif
688 extern void flush_caches(Class cls, BOOL flush_meta);
689 extern void flush_cache(Class cls);
690 extern BOOL _cache_fill(Class cls, Method smt, SEL sel);
691 extern void _cache_addForwardEntry(Class cls, SEL sel);
692 extern void _cache_free(Cache cache);
693
694 extern mutex_t cacheUpdateLock;
695
696 #if !__OBJC2__
697 // used by flush_caches outside objc-cache.m
698 extern void _cache_flush(Class cls);
699 #ifdef OBJC_INSTRUMENTED
700 extern unsigned int LinearFlushCachesCount;
701 extern unsigned int LinearFlushCachesVisitedCount;
702 extern unsigned int MaxLinearFlushCachesVisitedCount;
703 extern unsigned int NonlinearFlushCachesCount;
704 extern unsigned int NonlinearFlushCachesClassCount;
705 extern unsigned int NonlinearFlushCachesVisitedCount;
706 extern unsigned int MaxNonlinearFlushCachesVisitedCount;
707 extern unsigned int IdealFlushCachesCount;
708 extern unsigned int MaxIdealFlushCachesCount;
709 #endif
710 #endif
711
712 // objc-gdb.h
713 #if !TARGET_OS_WIN32
714 BOOL _objc_dumpHeap(auto_zone_t *zone, const char *filename);
715 #endif
716
717 // encoding.h
718 extern unsigned int encoding_getNumberOfArguments(const char *typedesc);
719 extern unsigned int encoding_getSizeOfArguments(const char *typedesc);
720 extern unsigned int encoding_getArgumentInfo(const char *typedesc, int arg, const char **type, int *offset);
721 extern void encoding_getReturnType(const char *t, char *dst, size_t dst_len);
722 extern char * encoding_copyReturnType(const char *t);
723 extern void encoding_getArgumentType(const char *t, unsigned int index, char *dst, size_t dst_len);
724 extern char *encoding_copyArgumentType(const char *t, unsigned int index);
725
726 // sync.h
727 extern void _destroySyncCache(struct SyncCache *cache);
728
729 // layout.h
730 typedef struct {
731 uint8_t *bits;
732 size_t bitCount;
733 size_t bitsAllocated;
734 BOOL weak;
735 } layout_bitmap;
736 extern layout_bitmap layout_bitmap_create(const unsigned char *layout_string, size_t layoutStringInstanceSize, size_t instanceSize, BOOL weak);
737 extern void layout_bitmap_free(layout_bitmap bits);
738 extern const unsigned char *layout_string_create(layout_bitmap bits);
739 extern void layout_bitmap_set_ivar(layout_bitmap bits, const char *type, size_t offset);
740 extern void layout_bitmap_grow(layout_bitmap *bits, size_t newCount);
741 extern void layout_bitmap_slide(layout_bitmap *bits, size_t oldPos, size_t newPos);
742 extern BOOL layout_bitmap_splat(layout_bitmap dst, layout_bitmap src,
743 size_t oldSrcInstanceSize);
744 extern BOOL layout_bitmap_or(layout_bitmap dst, layout_bitmap src, const char *msg);
745 extern BOOL layout_bitmap_clear(layout_bitmap dst, layout_bitmap src, const char *msg);
746 extern void layout_bitmap_print(layout_bitmap bits);
747
748
749 // fixme runtime
750 extern id look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler);
751 extern const char *map_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
752 extern const char *map_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
753 extern const char * load_images(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
754 extern BOOL load_images_nolock(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info infoList[]);
755 extern void unmap_image(const struct mach_header *mh, intptr_t vmaddr_slide);
756 extern void unmap_image_nolock(const struct mach_header *mh, intptr_t vmaddr_slide);
757 extern void _read_images(header_info **hList, uint32_t hCount);
758 extern void prepare_load_methods(header_info *hi);
759 extern void _unload_image(header_info *hi);
760 extern const char ** _objc_copyClassNamesForImage(header_info *hi, unsigned int *outCount);
761
762 extern Class _objc_allocateFutureClass(const char *name);
763
764
765 extern Property *copyPropertyList(struct objc_property_list *plist, unsigned int *outCount);
766
767
768 extern const header_info *_headerForClass(Class cls);
769
770 // fixme class
771 extern Property property_list_nth(const struct objc_property_list *plist, uint32_t i);
772 extern size_t property_list_size(const struct objc_property_list *plist);
773
774 extern Class _class_getSuperclass(Class cls);
775 extern BOOL _class_getInfo(Class cls, int info);
776 extern const char *_class_getName(Class cls);
777 extern size_t _class_getInstanceSize(Class cls);
778 extern Class _class_getMeta(Class cls);
779 extern BOOL _class_isMetaClass(Class cls);
780 extern Cache _class_getCache(Class cls);
781 extern void _class_setCache(Class cls, Cache cache);
782 extern BOOL _class_isInitializing(Class cls);
783 extern BOOL _class_isInitialized(Class cls);
784 extern void _class_setInitializing(Class cls);
785 extern void _class_setInitialized(Class cls);
786 extern Class _class_getNonMetaClass(Class cls);
787 extern Method _class_getMethod(Class cls, SEL sel);
788 extern Method _class_getMethodNoSuper(Class cls, SEL sel);
789 extern Method _class_getMethodNoSuper_nolock(Class cls, SEL sel);
790 extern BOOL _class_isLoadable(Class cls);
791 extern IMP _class_getLoadMethod(Class cls);
792 extern BOOL _class_hasLoadMethod(Class cls);
793 extern BOOL _class_hasCxxStructorsNoSuper(Class cls);
794 extern BOOL _class_shouldFinalizeOnMainThread(Class cls);
795 extern void _class_setFinalizeOnMainThread(Class cls);
796 extern BOOL _class_instancesHaveAssociatedObjects(Class cls);
797 extern void _class_assertInstancesHaveAssociatedObjects(Class cls);
798 extern BOOL _class_shouldGrowCache(Class cls);
799 extern void _class_setGrowCache(Class cls, BOOL grow);
800 extern Ivar _class_getVariable(Class cls, const char *name);
801
802 extern id _internal_class_createInstanceFromZone(Class cls, size_t extraBytes,
803 void *zone);
804 extern id _internal_object_dispose(id anObject);
805
806 extern Class gdb_class_getClass(Class cls);
807 extern BOOL class_instancesHaveAssociatedObjects(Class cls);
808 OBJC_EXPORT BOOL gdb_objc_isRuntimeLocked();
809
810 extern const char *_category_getName(Category cat);
811 extern const char *_category_getClassName(Category cat);
812 extern Class _category_getClass(Category cat);
813 extern IMP _category_getLoadMethod(Category cat);
814
815 #if !__OBJC2__
816 #define oldcls(cls) ((struct old_class *)cls)
817 #define oldprotocol(proto) ((struct old_protocol *)proto)
818 #define oldmethod(meth) ((struct old_method *)meth)
819 #define oldcategory(cat) ((struct old_category *)cat)
820 #define oldivar(ivar) ((struct old_ivar *)ivar)
821
822 static inline struct old_method *_method_asOld(Method m) { return (struct old_method *)m; }
823 static inline struct old_class *_class_asOld(Class cls) { return (struct old_class *)cls; }
824 static inline struct old_category *_category_asOld(Category cat) { return (struct old_category *)cat; }
825
826 extern void unload_class(struct old_class *cls);
827 Class _class_getNonexistentObjectClass(void);
828 #endif
829
830 extern BOOL object_cxxConstruct(id obj);
831 extern void object_cxxDestruct(id obj);
832
833 extern Method _class_resolveMethod(Class cls, SEL sel);
834 extern void log_and_fill_cache(Class cls, Class implementer, Method meth, SEL sel);
835
836 #if !__OBJC2__
837 #define CLS_CLASS 0x1
838 #define CLS_META 0x2
839 #define CLS_INITIALIZED 0x4
840 #define CLS_POSING 0x8
841 #define CLS_MAPPED 0x10
842 #define CLS_FLUSH_CACHE 0x20
843 #define CLS_GROW_CACHE 0x40
844 #define CLS_NEED_BIND 0x80
845 #define CLS_METHOD_ARRAY 0x100
846 // the JavaBridge constructs classes with these markers
847 #define CLS_JAVA_HYBRID 0x200
848 #define CLS_JAVA_CLASS 0x400
849 // thread-safe +initialize
850 #define CLS_INITIALIZING 0x800
851 // bundle unloading
852 #define CLS_FROM_BUNDLE 0x1000
853 // C++ ivar support
854 #define CLS_HAS_CXX_STRUCTORS 0x2000
855 // Lazy method list arrays
856 #define CLS_NO_METHOD_ARRAY 0x4000
857 // +load implementation
858 #define CLS_HAS_LOAD_METHOD 0x8000
859 // objc_allocateClassPair API
860 #define CLS_CONSTRUCTING 0x10000
861 // visibility=hidden
862 #define CLS_HIDDEN 0x20000
863 // GC: class has unsafe finalize method
864 #define CLS_FINALIZE_ON_MAIN_THREAD 0x40000
865 // Lazy property list arrays
866 #define CLS_NO_PROPERTY_ARRAY 0x80000
867 // +load implementation
868 #define CLS_CONNECTED 0x100000
869 #define CLS_LOADED 0x200000
870 // objc_allocateClassPair API
871 #define CLS_CONSTRUCTED 0x400000
872 // class is leaf for cache flushing
873 #define CLS_LEAF 0x800000
874 // class instances may have associative references
875 #define CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS 0x1000000
876 #endif
877
878 #define OBJC_WARN_DEPRECATED \
879 do { \
880 static int warned = 0; \
881 if (!warned) { \
882 warned = 1; \
883 _objc_warn_deprecated(__FUNCTION__, NULL); \
884 } \
885 } while (0) \
886
887 __END_DECLS
888
889 #endif /* _OBJC_PRIVATE_H_ */
890