]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-private.h
objc4-237.tar.gz
[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 #import <malloc/malloc.h>
59
60
61 /* Opaque cookie used in _getObjc... routines. File format independant.
62 * This is used in place of the mach_header. In fact, when compiling
63 * for NEXTSTEP, this is really a (struct mach_header *).
64 *
65 * had been: typedef void *objc_header;
66 */
67 #import <mach-o/loader.h>
68 typedef struct mach_header headerType;
69
70 #import <objc/Protocol.h>
71
72 typedef struct _ProtocolTemplate { @defs(Protocol) } ProtocolTemplate;
73 typedef struct _NXConstantStringTemplate {
74 Class isa;
75 void *characters;
76 unsigned int _length;
77 } NXConstantStringTemplate;
78
79 #define OBJC_CONSTANT_STRING_PTR NXConstantStringTemplate*
80 #define OBJC_CONSTANT_STRING_DEREF &
81 #define OBJC_PROTOCOL_PTR ProtocolTemplate*
82 #define OBJC_PROTOCOL_DEREF .
83
84 typedef struct {
85 uint32_t version; // currently 0
86 uint32_t flags;
87 } objc_image_info;
88
89 // masks for objc_image_info.flags
90 #define OBJC_IMAGE_IS_REPLACEMENT (1<<0)
91 #define _objcHeaderIsReplacement(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_IS_REPLACEMENT))
92
93 /* OBJC_IMAGE_IS_REPLACEMENT:
94 Don't load any classes
95 Don't load any categories
96 Do fix up selector refs (@selector points to them)
97 Do fix up class refs (@class and objc_msgSend points to them)
98 Do fix up protocols (@protocol points to them)
99 Future: do load new classes?
100 Future: do load new categories?
101 Future: do insert new methods on existing classes?
102 Future: do insert new methods on existing categories?
103 */
104
105
106 // both
107 OBJC_EXPORT headerType ** _getObjcHeaders();
108 OBJC_EXPORT Module _getObjcModules(headerType *head, int *nmodules);
109 OBJC_EXPORT Class * _getObjcClassRefs(headerType *head, int *nclasses);
110 OBJC_EXPORT void * _getObjcHeaderData(const headerType *head, unsigned *size);
111 OBJC_EXPORT const char * _getObjcHeaderName(headerType *head);
112 OBJC_EXPORT objc_image_info * _getObjcImageInfo(headerType *head);
113
114 // internal routines for delaying binding
115 void _objc_resolve_categories_for_class (struct objc_class * cls);
116 void _objc_bindClassIfNeeded(struct objc_class *cls);
117 void _objc_bindModuleContainingClass(struct objc_class * cls);
118
119 // someday a logging facility
120 // ObjC is assigned the range 0xb000 - 0xbfff for first parameter
121 #define trace(a, b, c, d) do {} while (0)
122
123
124
125 OBJC_EXPORT ProtocolTemplate * _getObjcProtocols(headerType *head, int *nprotos);
126 OBJC_EXPORT NXConstantStringTemplate *_getObjcStringObjects(headerType *head, int *nstrs);
127 OBJC_EXPORT SEL * _getObjcMessageRefs(headerType *head, int *nmess);
128
129 #define END_OF_METHODS_LIST ((struct objc_method_list*)-1)
130
131 typedef struct _header_info
132 {
133 const headerType * mhdr;
134 Module mod_ptr; // NOT adjusted by image_slide
135 unsigned int mod_count;
136 unsigned long image_slide;
137 void * objcData; // getObjcHeaderData result
138 unsigned objcDataSize; // getObjcHeaderData result
139 objc_image_info * info; // IS adjusted by image_slide
140 struct _header_info * next;
141 } header_info;
142 OBJC_EXPORT header_info *_objc_headerStart ();
143
144 OBJC_EXPORT int _objcModuleCount();
145 OBJC_EXPORT const char *_objcModuleNameAtIndex(int i);
146 OBJC_EXPORT Class objc_getOrigClass (const char *name);
147
148 extern struct objc_method_list **get_base_method_list(Class cls);
149
150
151 OBJC_EXPORT const char *__S(_nameForHeader) (const headerType*);
152
153 /* initialize */
154 OBJC_EXPORT void _sel_resolve_conflicts(headerType * header, unsigned long slide);
155 OBJC_EXPORT void _class_install_relationships(Class, long);
156 OBJC_EXPORT void *_objc_create_zone(void);
157
158 OBJC_EXPORT SEL sel_registerNameNoCopyNoLock(const char *str);
159 OBJC_EXPORT void sel_lock(void);
160 OBJC_EXPORT void sel_unlock(void);
161
162 /* selector fixup in method lists */
163
164 #define _OBJC_FIXED_UP ((void *)1771)
165
166 static inline struct objc_method_list *_objc_inlined_fixup_selectors_in_method_list(struct objc_method_list *mlist)
167 {
168 unsigned i, size;
169 Method method;
170 struct objc_method_list *old_mlist;
171
172 if ( ! mlist ) return (struct objc_method_list *)0;
173 if ( mlist->obsolete != _OBJC_FIXED_UP ) {
174 old_mlist = mlist;
175 size = sizeof(struct objc_method_list) - sizeof(struct objc_method) + old_mlist->method_count * sizeof(struct objc_method);
176 mlist = malloc_zone_malloc(_objc_create_zone(), size);
177 memmove(mlist, old_mlist, size);
178 sel_lock();
179 for ( i = 0; i < mlist->method_count; i += 1 ) {
180 method = &mlist->method_list[i];
181 method->method_name =
182 sel_registerNameNoCopyNoLock((const char *)method->method_name);
183 }
184 sel_unlock();
185 mlist->obsolete = _OBJC_FIXED_UP;
186 }
187 return mlist;
188 }
189
190 /* method lookup */
191 /* -- inline version of class_nextMethodList(Class, void **) -- */
192
193 static inline struct objc_method_list *_class_inlinedNextMethodList(Class cls, void **it)
194 {
195 struct objc_method_list ***iterator;
196
197 iterator = (struct objc_method_list***)it;
198 if (*iterator == NULL) {
199 *iterator = &((((struct objc_class *) cls)->methodLists)[0]);
200 }
201 else (*iterator) += 1;
202 // Check for list end
203 if ((**iterator == NULL) || (**iterator == END_OF_METHODS_LIST)) {
204 *it = nil;
205 return NULL;
206 }
207
208 **iterator = _objc_inlined_fixup_selectors_in_method_list(**iterator);
209
210 // Return method list pointer
211 return **iterator;
212 }
213
214 OBJC_EXPORT BOOL class_respondsToMethod(Class, SEL);
215 OBJC_EXPORT IMP class_lookupMethod(Class, SEL);
216 OBJC_EXPORT IMP class_lookupMethodInMethodList(struct objc_method_list *mlist, SEL sel);
217 OBJC_EXPORT IMP class_lookupNamedMethodInMethodList(struct objc_method_list *mlist, const char *meth_name);
218 OBJC_EXPORT void _objc_insertMethods( struct objc_method_list *mlist, struct objc_method_list ***list );
219 OBJC_EXPORT void _objc_removeMethods( struct objc_method_list *mlist, struct objc_method_list ***list );
220
221 OBJC_EXPORT IMP _cache_getImp(Class cls, SEL sel);
222 OBJC_EXPORT Method _cache_getMethod(Class cls, SEL sel, IMP objc_msgForward_imp);
223
224 /* message dispatcher */
225 OBJC_EXPORT IMP _class_lookupMethodAndLoadCache(Class, SEL);
226 OBJC_EXPORT id _objc_msgForward (id self, SEL sel, ...);
227
228 /* errors */
229 OBJC_EXPORT volatile void _objc_fatal(const char *fmt, ...);
230 OBJC_EXPORT volatile void _objc_error(id, const char *, va_list);
231 OBJC_EXPORT volatile void __objc_error(id, const char *, ...);
232 OBJC_EXPORT void _objc_inform(const char *fmt, ...);
233 OBJC_EXPORT void _objc_syslog(const char *fmt, ...);
234
235 /* magic */
236 OBJC_EXPORT Class _objc_getFreedObjectClass (void);
237 OBJC_EXPORT const struct objc_cache emptyCache;
238 OBJC_EXPORT void _objc_flush_caches (Class cls);
239
240 /* locking */
241 #define MUTEX_TYPE pthread_mutex_t*
242 #define OBJC_DECLARE_LOCK(MTX) pthread_mutex_t MTX = PTHREAD_MUTEX_INITIALIZER
243 OBJC_EXPORT pthread_mutex_t classLock;
244
245 /* nil handler object */
246 OBJC_EXPORT id _objc_nilReceiver;
247 OBJC_EXPORT id _objc_setNilReceiver(id newNilReceiver);
248 OBJC_EXPORT id _objc_getNilReceiver(void);
249
250
251 typedef struct {
252 long addressOffset;
253 long selectorOffset;
254 } FixupEntry;
255
256 static inline int selEqual( SEL s1, SEL s2 ) {
257 return (s1 == s2);
258 }
259
260 #define OBJC_LOCK(MUTEX) mutex_lock (MUTEX)
261 #define OBJC_UNLOCK(MUTEX) mutex_unlock (MUTEX)
262 #define OBJC_TRYLOCK(MUTEX) mutex_try_lock (MUTEX)
263
264 #if !defined(SEG_OBJC)
265 #define SEG_OBJC "__OBJC" /* objective-C runtime segment */
266 #endif
267
268
269
270
271 static __inline__ int _objc_strcmp(const unsigned char *s1, const unsigned char *s2) {
272 unsigned char c1, c2;
273 for ( ; (c1 = *s1) == (c2 = *s2); s1++, s2++)
274 if (c1 == '\0')
275 return 0;
276 return (c1 - c2);
277 }
278
279 static __inline__ unsigned int _objc_strhash(const unsigned char *s) {
280 unsigned int hash = 0;
281 for (;;) {
282 int a = *s++;
283 if (0 == a) break;
284 hash += (hash << 8) + a;
285 }
286 return hash;
287 }
288
289
290 // objc per-thread storage
291 OBJC_EXPORT pthread_key_t _objc_pthread_key;
292 typedef struct {
293 struct _objc_initializing_classes *initializingClasses; // for +initialize
294
295 // If you add new fields here, don't forget to update
296 // _objc_pthread_destroyspecific()
297
298 } _objc_pthread_data;
299
300
301 // Class state
302 #define ISCLASS(cls) ((((struct objc_class *) cls)->info & CLS_CLASS) != 0)
303 #define ISMETA(cls) ((((struct objc_class *) cls)->info & CLS_META) != 0)
304 #define GETMETA(cls) (ISMETA(cls) ? ((struct objc_class *) cls) : ((struct objc_class *) cls)->isa)
305 #define ISINITIALIZED(cls) ((((volatile long)GETMETA(cls)->info) & CLS_INITIALIZED) != 0)
306 #define ISINITIALIZING(cls) ((((volatile long)GETMETA(cls)->info) & CLS_INITIALIZING) != 0)
307
308
309 #endif /* _OBJC_PRIVATE_H_ */
310