]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-class.h
objc4-235.tar.gz
[apple/objc4.git] / runtime / objc-class.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-class.h
27 * Copyright 1988-1996, NeXT Software, Inc.
28 */
29
30 #ifndef _OBJC_CLASS_H_
31 #define _OBJC_CLASS_H_
32
33 #import <objc/objc.h>
34 /*
35 * Class Template
36 */
37 struct objc_class {
38 struct objc_class *isa;
39 struct objc_class *super_class;
40 const char *name;
41 long version;
42 long info;
43 long instance_size;
44 struct objc_ivar_list *ivars;
45
46 struct objc_method_list **methodLists;
47
48 struct objc_cache *cache;
49 struct objc_protocol_list *protocols;
50 };
51 #define CLS_GETINFO(cls,infomask) ((cls)->info & (infomask))
52 #define CLS_SETINFO(cls,infomask) ((cls)->info |= (infomask))
53
54 #define CLS_CLASS 0x1L
55 #define CLS_META 0x2L
56 #define CLS_INITIALIZED 0x4L
57 #define CLS_POSING 0x8L
58 #define CLS_MAPPED 0x10L
59 #define CLS_FLUSH_CACHE 0x20L
60 #define CLS_GROW_CACHE 0x40L
61 #define CLS_NEED_BIND 0x80L
62 #define CLS_METHOD_ARRAY 0x100L
63 // the JavaBridge constructs classes with these markers
64 #define CLS_JAVA_HYBRID 0x200L
65 #define CLS_JAVA_CLASS 0x400L
66 // thread-safe +initialize
67 #define CLS_INITIALIZING 0x800
68
69 /*
70 * (true as of 2001-9-24)
71 * Thread-safety note: changes to these flags are not atomic, so
72 * the only thing preventing lost updates is the timing of the changes.
73 *
74 * As long as the following are isolated from each other for any one class,
75 * nearly all flag updates will be safe:
76 * - compile-time
77 * - loading in one thread (not including +load) without messaging
78 * - initializing in one thread with messaging from that thread only
79 * - multi-threaded messaging with method caching
80 *
81 * The current code doesn't protect loading yet.
82 *
83 * Times when the flags may change:
84 * CLS_CLASS: compile-time, hand-built classes
85 * CLS_META: compile time, hand-built classes
86 * CLS_INITIALIZED: initialize
87 * CLS_POSING: unsafe, but posing has other thread-safety problems
88 * CLS_MAPPED: compile-time
89 * CLS_FLUSH_CACHE: messaging
90 * CLS_GROW_CACHE: messaging
91 * FLUSH_CACHE and GROW_CACHE are protected from each other by the
92 * cacheUpdateLock.
93 * CLS_NEED_BIND: load, initialize
94 * CLS_METHOD_ARRAY: load
95 * CLS_JAVA_HYBRID: hand-built classes
96 * CLS_JAVA_CLASS: hand-built classes, initialize
97 * CLS_INITIALIZING: initialize
98 *
99 * The only unsafe updates are:
100 * - posing (unsafe anyway)
101 * - hand-built classes (including JavaBridge classes)
102 * There is a short time between objc_addClass inserts the new class
103 * into the class_hash and the builder setting the right flags.
104 * A thread looking at the class_hash could send a message to the class
105 * and trigger initialization, and the changes to the initialization
106 * flags and the hand-adjusted flags could collide.
107 * Solution: don't do that.
108 */
109
110
111 /*
112 * Category Template
113 */
114 typedef struct objc_category *Category;
115
116 struct objc_category {
117 char *category_name;
118 char *class_name;
119 struct objc_method_list *instance_methods;
120 struct objc_method_list *class_methods;
121 struct objc_protocol_list *protocols;
122 };
123
124 /*
125 * Instance Variable Template
126 */
127 typedef struct objc_ivar *Ivar;
128
129 struct objc_ivar {
130 char *ivar_name;
131 char *ivar_type;
132 int ivar_offset;
133 #ifdef __alpha__
134 int space;
135 #endif
136 };
137
138 struct objc_ivar_list {
139 int ivar_count;
140 #ifdef __alpha__
141 int space;
142 #endif
143 struct objc_ivar ivar_list[1]; /* variable length structure */
144 };
145
146 OBJC_EXPORT Ivar object_setInstanceVariable(id, const char *name, void *);
147 OBJC_EXPORT Ivar object_getInstanceVariable(id, const char *name, void **);
148
149 /*
150 * Method Template
151 */
152 typedef struct objc_method *Method;
153
154 struct objc_method {
155 SEL method_name;
156 char *method_types;
157 IMP method_imp;
158 };
159
160 struct objc_method_list {
161 struct objc_method_list *obsolete;
162
163 int method_count;
164 #ifdef __alpha__
165 int space;
166 #endif
167 struct objc_method method_list[1]; /* variable length structure */
168 };
169
170 /* Protocol support */
171
172 @class Protocol;
173
174 struct objc_protocol_list {
175 struct objc_protocol_list *next;
176 int count;
177 Protocol *list[1];
178 };
179
180 /* Definitions of filer types */
181
182 #define _C_ID '@'
183 #define _C_CLASS '#'
184 #define _C_SEL ':'
185 #define _C_CHR 'c'
186 #define _C_UCHR 'C'
187 #define _C_SHT 's'
188 #define _C_USHT 'S'
189 #define _C_INT 'i'
190 #define _C_UINT 'I'
191 #define _C_LNG 'l'
192 #define _C_ULNG 'L'
193 #define _C_FLT 'f'
194 #define _C_DBL 'd'
195 #define _C_BFLD 'b'
196 #define _C_VOID 'v'
197 #define _C_UNDEF '?'
198 #define _C_PTR '^'
199 #define _C_CHARPTR '*'
200 #define _C_ARY_B '['
201 #define _C_ARY_E ']'
202 #define _C_UNION_B '('
203 #define _C_UNION_E ')'
204 #define _C_STRUCT_B '{'
205 #define _C_STRUCT_E '}'
206
207 /* Structure for method cache - allocated/sized at runtime */
208
209 typedef struct objc_cache * Cache;
210
211 #define CACHE_BUCKET_NAME(B) ((B)->method_name)
212 #define CACHE_BUCKET_IMP(B) ((B)->method_imp)
213 #define CACHE_BUCKET_VALID(B) (B)
214 #define CACHE_HASH(sel, mask) (((uarith_t)(sel)>>2) & (mask))
215 struct objc_cache {
216 unsigned int mask; /* total = mask + 1 */
217 unsigned int occupied;
218 Method buckets[1];
219 };
220
221 /* operations */
222 OBJC_EXPORT id class_createInstance(Class, unsigned idxIvars);
223 OBJC_EXPORT id class_createInstanceFromZone(Class, unsigned idxIvars, void *z);
224
225 OBJC_EXPORT void class_setVersion(Class, int);
226 OBJC_EXPORT int class_getVersion(Class);
227
228 OBJC_EXPORT Ivar class_getInstanceVariable(Class, const char *);
229 OBJC_EXPORT Method class_getInstanceMethod(Class, SEL);
230 OBJC_EXPORT Method class_getClassMethod(Class, SEL);
231
232 OBJC_EXPORT void class_addMethods(Class, struct objc_method_list *);
233 OBJC_EXPORT void class_removeMethods(Class, struct objc_method_list *);
234
235 OBJC_EXPORT Class class_poseAs(Class imposter, Class original);
236
237 OBJC_EXPORT unsigned method_getNumberOfArguments(Method);
238 OBJC_EXPORT unsigned method_getSizeOfArguments(Method);
239 OBJC_EXPORT unsigned method_getArgumentInfo(Method m, int arg, const char **type, int *offset);
240
241 // usage for nextMethodList
242 //
243 // void *iterator = 0;
244 // struct objc_method_list *mlist;
245 // while ( mlist = class_nextMethodList( cls, &iterator ) )
246 // ;
247 #define OBJC_NEXT_METHOD_LIST 1
248 OBJC_EXPORT struct objc_method_list *class_nextMethodList(Class, void **);
249
250 typedef void *marg_list;
251
252 #if defined(__ppc__) || defined(ppc)
253 #define marg_prearg_size 128
254 #else
255 #define marg_prearg_size 0
256 #endif
257
258 #define marg_malloc(margs, method) \
259 do { \
260 margs = (marg_list *)malloc (marg_prearg_size + ((7 + method_getSizeOfArguments(method)) & ~7)); \
261 } while (0)
262
263
264 #define marg_free(margs) \
265 do { \
266 free(margs); \
267 } while (0)
268
269 #define marg_adjustedOffset(method, offset) \
270 (marg_prearg_size + offset)
271
272
273
274
275 #define marg_getRef(margs, offset, type) \
276 ( (type *)((char *)margs + marg_adjustedOffset(method,offset) ) )
277
278 #define marg_getValue(margs, offset, type) \
279 ( *marg_getRef(margs, offset, type) )
280
281 #define marg_setValue(margs, offset, type, value) \
282 ( marg_getValue(margs, offset, type) = (value) )
283
284 /* Load categories and non-referenced classes from libraries. */
285
286 #endif /* _OBJC_CLASS_H_ */