]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-private.h
b15a828b1e0dbbf1ff1b7e19cca3d3e125c8375a
[apple/objc4.git] / runtime / objc-private.h
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * objc-private.h
27 * Copyright 1988-1996, NeXT Software, Inc.
28 */
29
30 #if !defined(_OBJC_PRIVATE_H_)
31 #define _OBJC_PRIVATE_H_
32
33 #import <objc/objc-api.h> // for OBJC_EXPORT
34
35 OBJC_EXPORT void checkUniqueness();
36
37 #import "objc-config.h"
38
39 #import <pthread.h>
40 #define mutex_alloc() (pthread_mutex_t*)calloc(1, sizeof(pthread_mutex_t))
41 #define mutex_init(m) pthread_mutex_init(m, NULL)
42 #define mutex_lock(m) pthread_mutex_lock(m)
43 #define mutex_try_lock(m) (! pthread_mutex_trylock(m))
44 #define mutex_unlock(m) pthread_mutex_unlock(m)
45 #define mutex_clear(m)
46 #define mutex_t pthread_mutex_t*
47 #define mutex MUTEX_DEFINE_ERROR
48 #import <sys/time.h>
49
50 #import <stdlib.h>
51 #import <stdarg.h>
52 #import <stdio.h>
53 #import <string.h>
54 #import <ctype.h>
55
56 #import <objc/objc-runtime.h>
57
58 #ifdef MACOSX_PANTHER
59 #import <malloc/malloc.h>
60 #else
61 // pre-Panther
62 #import <objc/malloc.h>
63 #endif
64
65
66 /* Opaque cookie used in _getObjc... routines. File format independant.
67 * This is used in place of the mach_header. In fact, when compiling
68 * for NEXTSTEP, this is really a (struct mach_header *).
69 *
70 * had been: typedef void *objc_header;
71 */
72 #import <mach-o/loader.h>
73 typedef struct mach_header headerType;
74
75 #import <objc/Protocol.h>
76
77 typedef struct _ProtocolTemplate { @defs(Protocol) } ProtocolTemplate;
78 typedef struct _NXConstantStringTemplate {
79 Class isa;
80 void *characters;
81 unsigned int _length;
82 } NXConstantStringTemplate;
83
84 #define OBJC_CONSTANT_STRING_PTR NXConstantStringTemplate*
85 #define OBJC_CONSTANT_STRING_DEREF &
86 #define OBJC_PROTOCOL_PTR ProtocolTemplate*
87 #define OBJC_PROTOCOL_DEREF .
88
89 typedef struct {
90 uint32_t version; // currently 0
91 uint32_t flags;
92 } objc_image_info;
93
94 // masks for objc_image_info.flags
95 #define OBJC_IMAGE_IS_REPLACEMENT (1<<0)
96 #define _objcHeaderIsReplacement(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_IS_REPLACEMENT))
97
98 /* OBJC_IMAGE_IS_REPLACEMENT:
99 Don't load any classes
100 Don't load any categories
101 Do fix up selector refs (@selector points to them)
102 Do fix up class refs (@class and objc_msgSend points to them)
103 Do fix up protocols (@protocol points to them)
104 Future: do load new classes?
105 Future: do load new categories?
106 Future: do insert new methods on existing classes?
107 Future: do insert new methods on existing categories?
108 */
109
110
111 // both
112 OBJC_EXPORT headerType ** _getObjcHeaders();
113 OBJC_EXPORT Module _getObjcModules(headerType *head, int *nmodules);
114 OBJC_EXPORT Class * _getObjcClassRefs(headerType *head, int *nclasses);
115 OBJC_EXPORT void * _getObjcHeaderData(const headerType *head, unsigned *size);
116 OBJC_EXPORT const char * _getObjcHeaderName(headerType *head);
117 OBJC_EXPORT objc_image_info * _getObjcImageInfo(headerType *head);
118
119 // internal routines for delaying binding
120 void _objc_resolve_categories_for_class (struct objc_class * cls);
121 void _objc_bindClassIfNeeded(struct objc_class *cls);
122 void _objc_bindModuleContainingClass(struct objc_class * cls);
123
124 // someday a logging facility
125 // ObjC is assigned the range 0xb000 - 0xbfff for first parameter
126 #define trace(a, b, c, d) do {} while (0)
127
128
129
130 OBJC_EXPORT ProtocolTemplate * _getObjcProtocols(headerType *head, int *nprotos);
131 OBJC_EXPORT NXConstantStringTemplate *_getObjcStringObjects(headerType *head, int *nstrs);
132 OBJC_EXPORT SEL * _getObjcMessageRefs(headerType *head, int *nmess);
133
134 #define END_OF_METHODS_LIST ((struct objc_method_list*)-1)
135
136 typedef struct _header_info
137 {
138 const headerType * mhdr;
139 Module mod_ptr; // NOT adjusted by image_slide
140 unsigned int mod_count;
141 unsigned long image_slide;
142 void * objcData; // getObjcHeaderData result
143 unsigned objcDataSize; // getObjcHeaderData result
144 objc_image_info * info; // IS adjusted by image_slide
145 struct _header_info * next;
146 } header_info;
147 OBJC_EXPORT header_info *_objc_headerStart ();
148
149 OBJC_EXPORT int _objcModuleCount();
150 OBJC_EXPORT const char *_objcModuleNameAtIndex(int i);
151 OBJC_EXPORT Class objc_getOrigClass (const char *name);
152
153 extern struct objc_method_list **get_base_method_list(Class cls);
154
155
156 OBJC_EXPORT const char *__S(_nameForHeader) (const headerType*);
157
158 /* initialize */
159 OBJC_EXPORT void _sel_resolve_conflicts(headerType * header, unsigned long slide);
160 OBJC_EXPORT void _class_install_relationships(Class, long);
161 OBJC_EXPORT void *_objc_create_zone(void);
162
163 OBJC_EXPORT SEL sel_registerNameNoCopyNoLock(const char *str);
164 OBJC_EXPORT void sel_lock(void);
165 OBJC_EXPORT void sel_unlock(void);
166
167 /* selector fixup in method lists */
168
169 #define _OBJC_FIXED_UP ((void *)1771)
170
171 static inline struct objc_method_list *_objc_inlined_fixup_selectors_in_method_list(struct objc_method_list *mlist)
172 {
173 unsigned i, size;
174 Method method;
175 struct objc_method_list *old_mlist;
176
177 if ( ! mlist ) return (struct objc_method_list *)0;
178 if ( mlist->obsolete != _OBJC_FIXED_UP ) {
179 old_mlist = mlist;
180 size = sizeof(struct objc_method_list) - sizeof(struct objc_method) + old_mlist->method_count * sizeof(struct objc_method);
181 mlist = malloc_zone_malloc(_objc_create_zone(), size);
182 memmove(mlist, old_mlist, size);
183 sel_lock();
184 for ( i = 0; i < mlist->method_count; i += 1 ) {
185 method = &mlist->method_list[i];
186 method->method_name =
187 sel_registerNameNoCopyNoLock((const char *)method->method_name);
188 }
189 sel_unlock();
190 mlist->obsolete = _OBJC_FIXED_UP;
191 }
192 return mlist;
193 }
194
195 /* method lookup */
196 /* -- inline version of class_nextMethodList(Class, void **) -- */
197
198 static inline struct objc_method_list *_class_inlinedNextMethodList(Class cls, void **it)
199 {
200 struct objc_method_list ***iterator;
201
202 iterator = (struct objc_method_list***)it;
203 if (*iterator == NULL) {
204 *iterator = &((((struct objc_class *) cls)->methodLists)[0]);
205 }
206 else (*iterator) += 1;
207 // Check for list end
208 if ((**iterator == NULL) || (**iterator == END_OF_METHODS_LIST)) {
209 *it = nil;
210 return NULL;
211 }
212
213 **iterator = _objc_inlined_fixup_selectors_in_method_list(**iterator);
214
215 // Return method list pointer
216 return **iterator;
217 }
218
219 OBJC_EXPORT BOOL class_respondsToMethod(Class, SEL);
220 OBJC_EXPORT IMP class_lookupMethod(Class, SEL);
221 OBJC_EXPORT IMP class_lookupMethodInMethodList(struct objc_method_list *mlist, SEL sel);
222 OBJC_EXPORT IMP class_lookupNamedMethodInMethodList(struct objc_method_list *mlist, const char *meth_name);
223 OBJC_EXPORT void _objc_insertMethods( struct objc_method_list *mlist, struct objc_method_list ***list );
224 OBJC_EXPORT void _objc_removeMethods( struct objc_method_list *mlist, struct objc_method_list ***list );
225
226 OBJC_EXPORT IMP _cache_getImp(Class cls, SEL sel);
227 OBJC_EXPORT Method _cache_getMethod(Class cls, SEL sel, IMP objc_msgForward_imp);
228
229 /* message dispatcher */
230 OBJC_EXPORT IMP _class_lookupMethodAndLoadCache(Class, SEL);
231 OBJC_EXPORT id _objc_msgForward (id self, SEL sel, ...);
232
233 /* errors */
234 OBJC_EXPORT volatile void _objc_fatal(const char *fmt, ...);
235 OBJC_EXPORT volatile void _objc_error(id, const char *, va_list);
236 OBJC_EXPORT volatile void __objc_error(id, const char *, ...);
237 OBJC_EXPORT void _objc_inform(const char *fmt, ...);
238 OBJC_EXPORT void _objc_syslog(const char *fmt, ...);
239
240 /* magic */
241 OBJC_EXPORT Class _objc_getFreedObjectClass (void);
242 OBJC_EXPORT const struct objc_cache emptyCache;
243 OBJC_EXPORT void _objc_flush_caches (Class cls);
244
245 /* locking */
246 #define MUTEX_TYPE pthread_mutex_t*
247 #define OBJC_DECLARE_LOCK(MTX) pthread_mutex_t MTX = PTHREAD_MUTEX_INITIALIZER
248 OBJC_EXPORT pthread_mutex_t classLock;
249
250 /* nil handler object */
251 OBJC_EXPORT id _objc_nilReceiver;
252 OBJC_EXPORT id _objc_setNilReceiver(id newNilReceiver);
253 OBJC_EXPORT id _objc_getNilReceiver(void);
254
255
256 typedef struct {
257 long addressOffset;
258 long selectorOffset;
259 } FixupEntry;
260
261 static inline int selEqual( SEL s1, SEL s2 ) {
262 return (s1 == s2);
263 }
264
265 #define OBJC_LOCK(MUTEX) mutex_lock (MUTEX)
266 #define OBJC_UNLOCK(MUTEX) mutex_unlock (MUTEX)
267 #define OBJC_TRYLOCK(MUTEX) mutex_try_lock (MUTEX)
268
269 #if !defined(SEG_OBJC)
270 #define SEG_OBJC "__OBJC" /* objective-C runtime segment */
271 #endif
272
273
274
275
276 static __inline__ int _objc_strcmp(const unsigned char *s1, const unsigned char *s2) {
277 unsigned char c1, c2;
278 for ( ; (c1 = *s1) == (c2 = *s2); s1++, s2++)
279 if (c1 == '\0')
280 return 0;
281 return (c1 - c2);
282 }
283
284 static __inline__ unsigned int _objc_strhash(const unsigned char *s) {
285 unsigned int hash = 0;
286 for (;;) {
287 int a = *s++;
288 if (0 == a) break;
289 hash += (hash << 8) + a;
290 }
291 return hash;
292 }
293
294
295 // objc per-thread storage
296 OBJC_EXPORT pthread_key_t _objc_pthread_key;
297 typedef struct {
298 struct _objc_initializing_classes *initializingClasses; // for +initialize
299
300 // If you add new fields here, don't forget to update
301 // _objc_pthread_destroyspecific()
302
303 } _objc_pthread_data;
304
305
306 // Class state
307 #define ISCLASS(cls) ((((struct objc_class *) cls)->info & CLS_CLASS) != 0)
308 #define ISMETA(cls) ((((struct objc_class *) cls)->info & CLS_META) != 0)
309 #define GETMETA(cls) (ISMETA(cls) ? ((struct objc_class *) cls) : ((struct objc_class *) cls)->isa)
310 #define ISINITIALIZED(cls) ((((volatile long)GETMETA(cls)->info) & CLS_INITIALIZED) != 0)
311 #define ISINITIALIZING(cls) ((((volatile long)GETMETA(cls)->info) & CLS_INITIALIZING) != 0)
312
313
314 #endif /* _OBJC_PRIVATE_H_ */
315