]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-private.h
9e90500c64ac8b9c7fa4584d8906c703cc7e8ea8
[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 #import <pthread.h>
39 #define mutex_alloc() (pthread_mutex_t*)calloc(1, sizeof(pthread_mutex_t))
40 #define mutex_init(m) pthread_mutex_init(m, NULL)
41 #define mutex_lock(m) pthread_mutex_lock(m)
42 #define mutex_try_lock(m) (! pthread_mutex_trylock(m))
43 #define mutex_unlock(m) pthread_mutex_unlock(m)
44 #define mutex_clear(m)
45 #define mutex_t pthread_mutex_t*
46 #define mutex MUTEX_DEFINE_ERROR
47 #import <sys/time.h>
48
49 #import <stdlib.h>
50 #import <stdarg.h>
51 #import <stdio.h>
52 #import <string.h>
53 #import <ctype.h>
54
55 #import <objc/objc-runtime.h>
56
57 // This needs <...> -- malloc.h is not ours, really...
58 #import <objc/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 // both
85 OBJC_EXPORT headerType ** _getObjcHeaders();
86 OBJC_EXPORT Module _getObjcModules(headerType *head, int *nmodules);
87 OBJC_EXPORT Class * _getObjcClassRefs(headerType *head, int *nclasses);
88 OBJC_EXPORT void * _getObjcHeaderData(headerType *head, unsigned *size);
89 OBJC_EXPORT const char * _getObjcHeaderName(headerType *head);
90
91 // internal routines for delaying binding
92 void _objc_resolve_categories_for_class (struct objc_class * cls);
93 void _objc_bindClassIfNeeded(struct objc_class *cls);
94 void _objc_bindModuleContainingClass(struct objc_class * cls);
95
96 // someday a logging facility
97 // ObjC is assigned the range 0xb000 - 0xbfff for first parameter
98 #define trace(a, b, c, d) do {} while (0)
99
100
101
102 OBJC_EXPORT ProtocolTemplate * _getObjcProtocols(headerType *head, int *nprotos);
103 OBJC_EXPORT NXConstantStringTemplate *_getObjcStringObjects(headerType *head, int *nstrs);
104 OBJC_EXPORT SEL * _getObjcMessageRefs(headerType *head, int *nmess);
105
106 #define END_OF_METHODS_LIST ((struct objc_method_list*)-1)
107
108 typedef struct _header_info
109 {
110 const headerType * mhdr;
111 Module mod_ptr;
112 unsigned int mod_count;
113 unsigned long image_slide;
114 struct _header_info * next;
115 } header_info;
116 OBJC_EXPORT header_info *_objc_headerStart ();
117
118 OBJC_EXPORT int _objcModuleCount();
119 OBJC_EXPORT const char *_objcModuleNameAtIndex(int i);
120 OBJC_EXPORT Class objc_getOrigClass (const char *name);
121
122 extern struct objc_method_list **get_base_method_list(Class cls);
123
124
125 OBJC_EXPORT const char *__S(_nameForHeader) (const headerType*);
126
127 /* initialize */
128 OBJC_EXPORT void _sel_resolve_conflicts(headerType * header, unsigned long slide);
129 OBJC_EXPORT void _class_install_relationships(Class, long);
130 OBJC_EXPORT void *_objc_create_zone(void);
131
132 OBJC_EXPORT SEL sel_registerNameNoCopy(const char *str);
133
134 /* selector fixup in method lists */
135
136 #define _OBJC_FIXED_UP ((void *)1771)
137
138 static inline struct objc_method_list *_objc_inlined_fixup_selectors_in_method_list(struct objc_method_list *mlist)
139 {
140 unsigned i, size;
141 Method method;
142 struct objc_method_list *old_mlist;
143
144 if ( ! mlist ) return (struct objc_method_list *)0;
145 if ( mlist->obsolete != _OBJC_FIXED_UP ) {
146 old_mlist = mlist;
147 size = sizeof(struct objc_method_list) - sizeof(struct objc_method) + old_mlist->method_count * sizeof(struct objc_method);
148 mlist = malloc_zone_malloc(_objc_create_zone(), size);
149 memmove(mlist, old_mlist, size);
150 for ( i = 0; i < mlist->method_count; i += 1 ) {
151 method = &mlist->method_list[i];
152 method->method_name =
153 sel_registerNameNoCopy((const char *)method->method_name);
154 }
155 mlist->obsolete = _OBJC_FIXED_UP;
156 }
157 return mlist;
158 }
159
160 /* method lookup */
161 /* -- inline version of class_nextMethodList(Class, void **) -- */
162
163 static inline struct objc_method_list *_class_inlinedNextMethodList(Class cls, void **it)
164 {
165 struct objc_method_list ***iterator;
166
167 iterator = (struct objc_method_list***)it;
168 if (*iterator == NULL) {
169 *iterator = &((((struct objc_class *) cls)->methodLists)[0]);
170 }
171 else (*iterator) += 1;
172 // Check for list end
173 if ((**iterator == NULL) || (**iterator == END_OF_METHODS_LIST)) {
174 *it = nil;
175 return NULL;
176 }
177
178 **iterator = _objc_inlined_fixup_selectors_in_method_list(**iterator);
179
180 // Return method list pointer
181 return **iterator;
182 }
183
184 OBJC_EXPORT BOOL class_respondsToMethod(Class, SEL);
185 OBJC_EXPORT IMP class_lookupMethod(Class, SEL);
186 OBJC_EXPORT IMP class_lookupMethodInMethodList(struct objc_method_list *mlist, SEL sel);
187 OBJC_EXPORT IMP class_lookupNamedMethodInMethodList(struct objc_method_list *mlist, const char *meth_name);
188 OBJC_EXPORT void _objc_insertMethods( struct objc_method_list *mlist, struct objc_method_list ***list );
189 OBJC_EXPORT void _objc_removeMethods( struct objc_method_list *mlist, struct objc_method_list ***list );
190
191 OBJC_EXPORT IMP _cache_getImp(Class cls, SEL sel);
192 OBJC_EXPORT Method _cache_getMethod(Class cls, SEL sel);
193
194 /* message dispatcher */
195 OBJC_EXPORT IMP _class_lookupMethodAndLoadCache(Class, SEL);
196 OBJC_EXPORT id _objc_msgForward (id self, SEL sel, ...);
197
198 /* errors */
199 OBJC_EXPORT volatile void __S(_objc_fatal)(const char *message);
200 OBJC_EXPORT volatile void _objc_error(id, const char *, va_list);
201 OBJC_EXPORT volatile void __objc_error(id, const char *, ...);
202 OBJC_EXPORT void _objc_inform(const char *fmt, ...);
203 OBJC_EXPORT void _objc_syslog(const char *fmt, ...);
204
205 /* magic */
206 OBJC_EXPORT Class _objc_getFreedObjectClass (void);
207 OBJC_EXPORT const struct objc_cache emptyCache;
208 OBJC_EXPORT void _objc_flush_caches (Class cls);
209
210 /* locking */
211 #define MUTEX_TYPE pthread_mutex_t*
212 #define OBJC_DECLARE_LOCK(MTX) pthread_mutex_t MTX = PTHREAD_MUTEX_INITIALIZER
213 OBJC_EXPORT pthread_mutex_t classLock;
214
215 // _objc_msgNil is actually (unsigned dummy, id, SEL) for i386;
216 // currently not implemented for any sparc or hppa platforms
217 OBJC_EXPORT void (*_objc_msgNil)(id, SEL);
218
219 typedef struct {
220 long addressOffset;
221 long selectorOffset;
222 } FixupEntry;
223
224 static inline int selEqual( SEL s1, SEL s2 ) {
225 return (s1 == s2);
226 }
227
228 #define OBJC_LOCK(MUTEX) mutex_lock (MUTEX)
229 #define OBJC_UNLOCK(MUTEX) mutex_unlock (MUTEX)
230 #define OBJC_TRYLOCK(MUTEX) mutex_try_lock (MUTEX)
231
232 #if !defined(SEG_OBJC)
233 #define SEG_OBJC "__OBJC" /* objective-C runtime segment */
234 #endif
235
236
237
238
239 static __inline__ int _objc_strcmp(const unsigned char *s1, const unsigned char *s2) {
240 int a, b, idx = 0;
241 for (;;) {
242 a = s1[idx];
243 b = s2[idx];
244 if (a != b || 0 == a) break;
245 idx++;
246 }
247 return a - b;
248 }
249
250 static __inline__ unsigned int _objc_strhash(const unsigned char *s) {
251 unsigned int hash = 0;
252 for (;;) {
253 int a = *s++;
254 if (0 == a) break;
255 hash += (hash << 8) + a;
256 }
257 return hash;
258 }
259
260
261 // objc per-thread storage
262 OBJC_EXPORT pthread_key_t _objc_pthread_key;
263 typedef struct {
264 struct _objc_initializing_classes *initializingClasses; // for +initialize
265
266 // If you add new fields here, don't forget to update
267 // _objc_pthread_destroyspecific()
268
269 } _objc_pthread_data;
270
271
272 // Class state
273 #define ISCLASS(cls) ((((struct objc_class *) cls)->info & CLS_CLASS) != 0)
274 #define ISMETA(cls) ((((struct objc_class *) cls)->info & CLS_META) != 0)
275 #define GETMETA(cls) (ISMETA(cls) ? ((struct objc_class *) cls) : ((struct objc_class *) cls)->isa)
276 #define ISINITIALIZED(cls) ((((volatile long)GETMETA(cls)->info) & CLS_INITIALIZED) != 0)
277 #define ISINITIALIZING(cls) ((((volatile long)GETMETA(cls)->info) & CLS_INITIALIZING) != 0)
278
279
280 #endif /* _OBJC_PRIVATE_H_ */
281