]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-private.h
3b22986dcb07cdf338f79138e9bca944142149a5
[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 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * objc-private.h
26 * Copyright 1988-1996, NeXT Software, Inc.
27 */
28
29 #if !defined(_OBJC_PRIVATE_H_)
30 #define _OBJC_PRIVATE_H_
31
32 #import <objc/objc-api.h> // for OBJC_EXPORT
33
34 OBJC_EXPORT void checkUniqueness();
35
36 #import "objc-config.h"
37
38 #if defined(NeXT_PDO)
39 #define LITERAL_STRING_OBJECTS
40 #import <mach/cthreads_private.h>
41 #if defined(WIN32)
42 #import <winnt-pdo.h>
43 #import <ntunix.h>
44 #else
45 #import <pdo.h> // for pdo_malloc and pdo_free defines
46 #import <sys/time.h>
47 #endif
48 #else
49 #import <pthread.h>
50 #define mutex_alloc() (pthread_mutex_t*)calloc(1, sizeof(pthread_mutex_t))
51 #define mutex_init(m) pthread_mutex_init(m, NULL)
52 #define mutex_lock(m) pthread_mutex_lock(m)
53 #define mutex_try_lock(m) (! pthread_mutex_trylock(m))
54 #define mutex_unlock(m) pthread_mutex_unlock(m)
55 #define mutex_clear(m)
56 #define mutex_t pthread_mutex_t*
57 #define mutex MUTEX_DEFINE_ERROR
58 #import <sys/time.h>
59 #endif
60
61 #import <stdlib.h>
62 #import <stdarg.h>
63 #import <stdio.h>
64 #import <string.h>
65 #import <ctype.h>
66
67 #import <objc/objc-runtime.h>
68
69 // This needs <...> -- malloc.h is not ours, really...
70 #import <objc/malloc.h>
71
72
73 /* Opaque cookie used in _getObjc... routines. File format independant.
74 * This is used in place of the mach_header. In fact, when compiling
75 * for NEXTSTEP, this is really a (struct mach_header *).
76 *
77 * had been: typedef void *objc_header;
78 */
79 #if defined(NeXT_PDO)
80 typedef void headerType;
81 #else
82 #import <mach-o/loader.h>
83 typedef struct mach_header headerType;
84 #endif
85
86 #import <objc/Protocol.h>
87
88 typedef struct _ProtocolTemplate { @defs(Protocol) } ProtocolTemplate;
89 typedef struct _NXConstantStringTemplate {
90 Class isa;
91 void *characters;
92 unsigned int _length;
93 } NXConstantStringTemplate;
94
95 #if defined(NeXT_PDO)
96 #define OBJC_CONSTANT_STRING_PTR NXConstantStringTemplate**
97 #define OBJC_CONSTANT_STRING_DEREF
98 #define OBJC_PROTOCOL_PTR ProtocolTemplate**
99 #define OBJC_PROTOCOL_DEREF ->
100 #elif defined(__MACH__)
101 #define OBJC_CONSTANT_STRING_PTR NXConstantStringTemplate*
102 #define OBJC_CONSTANT_STRING_DEREF &
103 #define OBJC_PROTOCOL_PTR ProtocolTemplate*
104 #define OBJC_PROTOCOL_DEREF .
105 #endif
106
107 // both
108 OBJC_EXPORT headerType ** _getObjcHeaders();
109 OBJC_EXPORT Module _getObjcModules(headerType *head, int *nmodules);
110 OBJC_EXPORT Class * _getObjcClassRefs(headerType *head, int *nclasses);
111 OBJC_EXPORT void * _getObjcHeaderData(headerType *head, unsigned *size);
112 OBJC_EXPORT const char * _getObjcHeaderName(headerType *head);
113
114 #if defined(NeXT_PDO) // GENERIC_OBJ_FILE
115 OBJC_EXPORT ProtocolTemplate ** _getObjcProtocols(headerType *head, int *nprotos);
116 OBJC_EXPORT NXConstantStringTemplate **_getObjcStringObjects(headerType *head, int *nstrs);
117 #elif defined(__MACH__)
118 OBJC_EXPORT ProtocolTemplate * _getObjcProtocols(headerType *head, int *nprotos);
119 OBJC_EXPORT NXConstantStringTemplate *_getObjcStringObjects(headerType *head, int *nstrs);
120 OBJC_EXPORT SEL * _getObjcMessageRefs(headerType *head, int *nmess);
121 #endif
122
123 #define END_OF_METHODS_LIST ((struct objc_method_list*)-1)
124
125 struct header_info
126 {
127 const headerType * mhdr;
128 Module mod_ptr;
129 unsigned int mod_count;
130 unsigned long image_slide;
131 unsigned int objcSize;
132 };
133 typedef struct header_info header_info;
134 OBJC_EXPORT header_info *_objc_headerVector (const headerType * const *machhdrs);
135 OBJC_EXPORT unsigned int _objc_headerCount (void);
136 OBJC_EXPORT void _objc_addHeader (const headerType *header, unsigned long vmaddr_slide);
137
138 OBJC_EXPORT int _objcModuleCount();
139 OBJC_EXPORT const char *_objcModuleNameAtIndex(int i);
140 OBJC_EXPORT Class objc_getOrigClass (const char *name);
141
142 extern struct objc_method_list **get_base_method_list(Class cls);
143
144
145 OBJC_EXPORT const char *__S(_nameForHeader) (const headerType*);
146
147 /* initialize */
148 OBJC_EXPORT void _sel_resolve_conflicts(headerType * header, unsigned long slide);
149 OBJC_EXPORT void _class_install_relationships(Class, long);
150 OBJC_EXPORT void _objc_add_category(Category, int);
151 OBJC_EXPORT void *_objc_create_zone(void);
152
153 OBJC_EXPORT SEL sel_registerNameNoCopy(const char *str);
154
155 /* selector fixup in method lists */
156
157 #define _OBJC_FIXED_UP ((void *)1771)
158
159 static inline struct objc_method_list *_objc_inlined_fixup_selectors_in_method_list(struct objc_method_list *mlist)
160 {
161 unsigned i, size;
162 Method method;
163 struct objc_method_list *old_mlist;
164
165 if ( ! mlist ) return (struct objc_method_list *)0;
166 if ( mlist->obsolete != _OBJC_FIXED_UP ) {
167 old_mlist = mlist;
168 size = sizeof(struct objc_method_list) - sizeof(struct objc_method) + old_mlist->method_count * sizeof(struct objc_method);
169 mlist = malloc_zone_malloc(_objc_create_zone(), size);
170 memmove(mlist, old_mlist, size);
171 for ( i = 0; i < mlist->method_count; i += 1 ) {
172 method = &mlist->method_list[i];
173 method->method_name =
174 sel_registerNameNoCopy((const char *)method->method_name);
175 }
176 mlist->obsolete = _OBJC_FIXED_UP;
177 }
178 return mlist;
179 }
180
181 /* method lookup */
182 /* -- inline version of class_nextMethodList(Class, void **) -- */
183
184 static inline struct objc_method_list *_class_inlinedNextMethodList(Class cls, void **it)
185 {
186 struct objc_method_list ***iterator;
187
188 iterator = (struct objc_method_list***)it;
189 if (*iterator == NULL) {
190 *iterator = &((((struct objc_class *) cls)->methodLists)[0]);
191 }
192 else (*iterator) += 1;
193 // Check for list end
194 if ((**iterator == NULL) || (**iterator == END_OF_METHODS_LIST)) {
195 *it = nil;
196 return NULL;
197 }
198
199 **iterator = _objc_inlined_fixup_selectors_in_method_list(**iterator);
200
201 // Return method list pointer
202 return **iterator;
203 }
204
205 OBJC_EXPORT BOOL class_respondsToMethod(Class, SEL);
206 OBJC_EXPORT IMP class_lookupMethod(Class, SEL);
207 OBJC_EXPORT IMP class_lookupMethodInMethodList(struct objc_method_list *mlist, SEL sel);
208 OBJC_EXPORT IMP class_lookupNamedMethodInMethodList(struct objc_method_list *mlist, const char *meth_name);
209 OBJC_EXPORT void _objc_insertMethods( struct objc_method_list *mlist, struct objc_method_list ***list );
210 OBJC_EXPORT void _objc_removeMethods( struct objc_method_list *mlist, struct objc_method_list ***list );
211
212 /* message dispatcher */
213 OBJC_EXPORT Cache _cache_create(Class);
214 OBJC_EXPORT IMP _class_lookupMethodAndLoadCache(Class, SEL);
215 OBJC_EXPORT id _objc_msgForward (id self, SEL sel, ...);
216
217 /* errors */
218 OBJC_EXPORT volatile void __S(_objc_fatal)(const char *message);
219 OBJC_EXPORT volatile void _objc_error(id, const char *, va_list);
220 OBJC_EXPORT volatile void __objc_error(id, const char *, ...);
221 OBJC_EXPORT void _objc_inform(const char *fmt, ...);
222 OBJC_EXPORT void _NXLogError(const char *format, ...);
223
224 /* magic */
225 OBJC_EXPORT Class _objc_getFreedObjectClass (void);
226 OBJC_EXPORT const struct objc_cache emptyCache;
227 OBJC_EXPORT void _objc_flush_caches (Class cls);
228
229 /* locking */
230 #if defined(NeXT_PDO)
231 #if defined(WIN32)
232 #define MUTEX_TYPE long
233 #define OBJC_DECLARE_LOCK(MUTEX) MUTEX_TYPE MUTEX = 0L;
234 #elif defined(sparc)
235 #define MUTEX_TYPE long
236 #define OBJC_DECLARE_LOCK(MUTEX) MUTEX_TYPE MUTEX = 0L;
237 #elif defined(__alpha__)
238 #define MUTEX_TYPE long
239 #define OBJC_DECLARE_LOCK(MUTEX) MUTEX_TYPE MUTEX = 0L;
240 #elif defined(__hpux__) || defined(hpux)
241 typedef struct { int a; int b; int c; int d; } __mutex_struct;
242 #define MUTEX_TYPE __mutex_struct
243 #define OBJC_DECLARE_LOCK(MUTEX) MUTEX_TYPE MUTEX = { 1, 1, 1, 1 };
244 #else // unknown pdo platform
245 #define MUTEX_TYPE long
246 #define OBJC_DECLARE_LOCK(MUTEX) struct mutex MUTEX = { 0 };
247 #endif // WIN32
248 OBJC_EXPORT MUTEX_TYPE classLock;
249 OBJC_EXPORT MUTEX_TYPE messageLock;
250 #else
251 #define MUTEX_TYPE pthread_mutex_t*
252 #define OBJC_DECLARE_LOCK(MTX) pthread_mutex_t MTX = PTHREAD_MUTEX_INITIALIZER
253 OBJC_EXPORT pthread_mutex_t classLock;
254 OBJC_EXPORT pthread_mutex_t messageLock;
255 #endif // NeXT_PDO
256
257 OBJC_EXPORT int _objc_multithread_mask;
258
259 // _objc_msgNil is actually (unsigned dummy, id, SEL) for i386;
260 // currently not implemented for any sparc or hppa platforms
261 OBJC_EXPORT void (*_objc_msgNil)(id, SEL);
262
263 typedef struct {
264 long addressOffset;
265 long selectorOffset;
266 } FixupEntry;
267
268 static inline int selEqual( SEL s1, SEL s2 ) {
269 OBJC_EXPORT int rocketLaunchingDebug;
270 if ( rocketLaunchingDebug )
271 checkUniqueness(s1, s2);
272 return (s1 == s2);
273 }
274
275 #if defined(OBJC_COLLECTING_CACHE)
276 #define OBJC_LOCK(MUTEX) mutex_lock (MUTEX)
277 #define OBJC_UNLOCK(MUTEX) mutex_unlock (MUTEX)
278 #define OBJC_TRYLOCK(MUTEX) mutex_try_lock (MUTEX)
279 #elif defined(NeXT_PDO)
280 #if !defined(WIN32)
281 /* Where are these defined? NT should probably be using them! */
282 OBJC_EXPORT void _objc_private_lock(MUTEX_TYPE*);
283 OBJC_EXPORT void _objc_private_unlock(MUTEX_TYPE*);
284
285 /* I don't think this should be commented out for NT, should it? */
286 #define OBJC_LOCK(MUTEX) \
287 do {if (!_objc_multithread_mask) \
288 _objc_private_lock(MUTEX);} while(0)
289 #define OBJC_UNLOCK(MUTEX) \
290 do {if (!_objc_multithread_mask) \
291 _objc_private_unlock(MUTEX);} while(0)
292 #else
293 #define OBJC_LOCK(MUTEX) \
294 do {if (!_objc_multithread_mask) \
295 if( *MUTEX == 0 ) *MUTEX = 1;} while(0)
296 #define OBJC_UNLOCK(MUTEX) \
297 do {if (!_objc_multithread_mask) \
298 *MUTEX = 0;} while(0)
299 #endif // WIN32
300
301 #else // not NeXT_PDO
302 #define OBJC_LOCK(MUTEX) \
303 do \
304 { \
305 if (!_objc_multithread_mask) \
306 mutex_lock (MUTEX); \
307 } \
308 while (0)
309
310 #define OBJC_UNLOCK(MUTEX) \
311 do \
312 { \
313 if (!_objc_multithread_mask) \
314 mutex_unlock (MUTEX); \
315 } \
316 while (0)
317 #endif /* OBJC_COLLECTING_CACHE */
318
319 #if !defined(SEG_OBJC)
320 #define SEG_OBJC "__OBJC" /* objective-C runtime segment */
321 #endif
322
323 #if defined(NeXT_PDO)
324 // GENERIC_OBJ_FILE
325 void send_load_message_to_category(Category cat, void *header_addr);
326 void send_load_message_to_class(Class cls, void *header_addr);
327 #endif
328
329 #if !defined(__MACH__)
330 typedef struct _objcSectionStruct {
331 void **data; /* Pointer to array */
332 int count; /* # of elements */
333 int size; /* sizeof an element */
334 } objcSectionStruct;
335
336 typedef struct _objcModHeader {
337 char * name;
338 objcSectionStruct Modules;
339 objcSectionStruct Classes;
340 objcSectionStruct Methods;
341 objcSectionStruct Protocols;
342 objcSectionStruct StringObjects;
343 } objcModHeader;
344 #endif
345
346
347 static __inline__ int _objc_strcmp(const unsigned char *s1, const unsigned char *s2) {
348 int a, b, idx = 0;
349 for (;;) {
350 a = s1[idx];
351 b = s2[idx];
352 if (a != b || 0 == a) break;
353 idx++;
354 }
355 return a - b;
356 }
357
358 static __inline__ unsigned int _objc_strhash(const unsigned char *s) {
359 unsigned int hash = 0;
360 for (;;) {
361 int a = *s++;
362 if (0 == a) break;
363 hash += (hash << 8) + a;
364 }
365 return hash;
366 }
367
368 #endif /* _OBJC_PRIVATE_H_ */
369