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