]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-runtime-old.h
objc4-680.tar.gz
[apple/objc4.git] / runtime / objc-runtime-old.h
1 /*
2 * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #ifndef _OBJC_RUNTIME_OLD_H
25 #define _OBJC_RUNTIME_OLD_H
26
27 #include "objc-private.h"
28
29 #define CLS_CLASS 0x1
30 #define CLS_META 0x2
31 #define CLS_INITIALIZED 0x4
32 #define CLS_POSING 0x8
33 #define CLS_MAPPED 0x10
34 #define CLS_FLUSH_CACHE 0x20
35 #define CLS_GROW_CACHE 0x40
36 #define CLS_NEED_BIND 0x80
37 #define CLS_METHOD_ARRAY 0x100
38 // the JavaBridge constructs classes with these markers
39 #define CLS_JAVA_HYBRID 0x200
40 #define CLS_JAVA_CLASS 0x400
41 // thread-safe +initialize
42 #define CLS_INITIALIZING 0x800
43 // bundle unloading
44 #define CLS_FROM_BUNDLE 0x1000
45 // C++ ivar support
46 #define CLS_HAS_CXX_STRUCTORS 0x2000
47 // Lazy method list arrays
48 #define CLS_NO_METHOD_ARRAY 0x4000
49 // +load implementation
50 #define CLS_HAS_LOAD_METHOD 0x8000
51 // objc_allocateClassPair API
52 #define CLS_CONSTRUCTING 0x10000
53 // visibility=hidden
54 #define CLS_HIDDEN 0x20000
55 // GC: class has unsafe finalize method
56 #define CLS_FINALIZE_ON_MAIN_THREAD 0x40000
57 // Lazy property list arrays
58 #define CLS_NO_PROPERTY_ARRAY 0x80000
59 // +load implementation
60 #define CLS_CONNECTED 0x100000
61 #define CLS_LOADED 0x200000
62 // objc_allocateClassPair API
63 #define CLS_CONSTRUCTED 0x400000
64 // class is leaf for cache flushing
65 #define CLS_LEAF 0x800000
66 // class instances may have associative references
67 #define CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS 0x1000000
68 // class has instance-specific GC layout
69 #define CLS_HAS_INSTANCE_SPECIFIC_LAYOUT 0x2000000
70
71
72 // Terminator for array of method lists
73 #define END_OF_METHODS_LIST ((struct old_method_list*)-1)
74
75 #define ISCLASS(cls) (((cls)->info & CLS_CLASS) != 0)
76 #define ISMETA(cls) (((cls)->info & CLS_META) != 0)
77 #define GETMETA(cls) (ISMETA(cls) ? (cls) : (cls)->ISA())
78
79
80 struct objc_class : objc_object {
81 Class superclass;
82 const char *name;
83 uint32_t version;
84 uint32_t info;
85 uint32_t instance_size;
86 struct old_ivar_list *ivars;
87 struct old_method_list **methodLists;
88 Cache cache;
89 struct old_protocol_list *protocols;
90 // CLS_EXT only
91 const uint8_t *ivar_layout;
92 struct old_class_ext *ext;
93
94 void setInfo(uint32_t set) {
95 OSAtomicOr32Barrier(set, (volatile uint32_t *)&info);
96 }
97
98 void clearInfo(uint32_t clear) {
99 OSAtomicXor32Barrier(clear, (volatile uint32_t *)&info);
100 }
101
102
103 // set and clear must not overlap
104 void changeInfo(uint32_t set, uint32_t clear) {
105 assert((set & clear) == 0);
106
107 uint32_t oldf, newf;
108 do {
109 oldf = this->info;
110 newf = (oldf | set) & ~clear;
111 } while (!OSAtomicCompareAndSwap32Barrier(oldf, newf, (volatile int32_t *)&info));
112 }
113
114 bool hasCxxCtor() {
115 // set_superclass propagates the flag from the superclass.
116 return info & CLS_HAS_CXX_STRUCTORS;
117 }
118
119 bool hasCxxDtor() {
120 return hasCxxCtor(); // one bit for both ctor and dtor
121 }
122
123 bool hasCustomRR() {
124 return true;
125 }
126 void setHasCustomRR(bool = false) { }
127 void setHasDefaultRR() { }
128 void printCustomRR(bool) { }
129
130 bool hasCustomAWZ() {
131 return true;
132 }
133 void setHasCustomAWZ(bool = false) { }
134 void setHasDefaultAWZ() { }
135 void printCustomAWZ(bool) { }
136
137 bool instancesHaveAssociatedObjects() {
138 return info & CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS;
139 }
140
141 void setInstancesHaveAssociatedObjects() {
142 setInfo(CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS);
143 }
144
145 bool shouldGrowCache() {
146 return info & CLS_GROW_CACHE;
147 }
148
149 void setShouldGrowCache(bool grow) {
150 if (grow) setInfo(CLS_GROW_CACHE);
151 else clearInfo(CLS_GROW_CACHE);
152 }
153
154 bool shouldFinalizeOnMainThread() {
155 return info & CLS_FINALIZE_ON_MAIN_THREAD;
156 }
157
158 void setShouldFinalizeOnMainThread() {
159 setInfo(CLS_FINALIZE_ON_MAIN_THREAD);
160 }
161
162 // +initialize bits are stored on the metaclass only
163 bool isInitializing() {
164 return getMeta()->info & CLS_INITIALIZING;
165 }
166
167 // +initialize bits are stored on the metaclass only
168 void setInitializing() {
169 getMeta()->setInfo(CLS_INITIALIZING);
170 }
171
172 // +initialize bits are stored on the metaclass only
173 bool isInitialized() {
174 return getMeta()->info & CLS_INITIALIZED;
175 }
176
177 // +initialize bits are stored on the metaclass only
178 void setInitialized() {
179 getMeta()->changeInfo(CLS_INITIALIZED, CLS_INITIALIZING);
180 }
181
182 bool isLoadable() {
183 // A class registered for +load is ready for +load to be called
184 // if it is connected.
185 return isConnected();
186 }
187
188 IMP getLoadMethod();
189
190 bool isFuture();
191
192 bool isConnected();
193
194 const char *mangledName() { return name; }
195 const char *demangledName() { return name; }
196 const char *nameForLogging() { return name; }
197
198 bool isMetaClass() {
199 return info & CLS_META;
200 }
201
202 // NOT identical to this->ISA() when this is a metaclass
203 Class getMeta() {
204 if (isMetaClass()) return (Class)this;
205 else return this->ISA();
206 }
207
208 // May be unaligned depending on class's ivars.
209 uint32_t unalignedInstanceSize() {
210 return instance_size;
211 }
212
213 // Class's ivar size rounded up to a pointer-size boundary.
214 uint32_t alignedInstanceSize() {
215 return (unalignedInstanceSize() + WORD_MASK) & ~WORD_MASK;
216 }
217
218 size_t instanceSize(size_t extraBytes) {
219 size_t size = alignedInstanceSize() + extraBytes;
220 // CF requires all objects be at least 16 bytes.
221 if (size < 16) size = 16;
222 return size;
223 }
224
225 };
226
227 struct old_class_ext {
228 uint32_t size;
229 const uint8_t *weak_ivar_layout;
230 struct old_property_list **propertyLists;
231 };
232
233 struct old_category {
234 char *category_name;
235 char *class_name;
236 struct old_method_list *instance_methods;
237 struct old_method_list *class_methods;
238 struct old_protocol_list *protocols;
239 uint32_t size;
240 struct old_property_list *instance_properties;
241 };
242
243 struct old_ivar {
244 char *ivar_name;
245 char *ivar_type;
246 int ivar_offset;
247 #ifdef __LP64__
248 int space;
249 #endif
250 };
251
252 struct old_ivar_list {
253 int ivar_count;
254 #ifdef __LP64__
255 int space;
256 #endif
257 /* variable length structure */
258 struct old_ivar ivar_list[1];
259 };
260
261
262 struct old_method {
263 SEL method_name;
264 char *method_types;
265 IMP method_imp;
266 };
267
268 struct old_method_list {
269 void *obsolete;
270
271 int method_count;
272 #ifdef __LP64__
273 int space;
274 #endif
275 /* variable length structure */
276 struct old_method method_list[1];
277 };
278
279 struct old_protocol {
280 Class isa;
281 const char *protocol_name;
282 struct old_protocol_list *protocol_list;
283 struct objc_method_description_list *instance_methods;
284 struct objc_method_description_list *class_methods;
285 };
286
287 struct old_protocol_list {
288 struct old_protocol_list *next;
289 long count;
290 struct old_protocol *list[1];
291 };
292
293 struct old_protocol_ext {
294 uint32_t size;
295 struct objc_method_description_list *optional_instance_methods;
296 struct objc_method_description_list *optional_class_methods;
297 struct old_property_list *instance_properties;
298 const char **extendedMethodTypes;
299 };
300
301
302 struct old_property {
303 const char *name;
304 const char *attributes;
305 };
306
307 struct old_property_list {
308 uint32_t entsize;
309 uint32_t count;
310 struct old_property first;
311 };
312
313
314 #include "hashtable2.h"
315
316 __BEGIN_DECLS
317
318 #define oldprotocol(proto) ((struct old_protocol *)proto)
319 #define oldmethod(meth) ((struct old_method *)meth)
320 #define oldcategory(cat) ((struct old_category *)cat)
321 #define oldivar(ivar) ((struct old_ivar *)ivar)
322 #define oldproperty(prop) ((struct old_property *)prop)
323
324 extern NXHashTable *class_hash;
325
326 extern void unload_class(Class cls);
327
328 extern IMP lookupNamedMethodInMethodList(struct old_method_list *mlist, const char *meth_name);
329 extern void _objc_insertMethods(Class cls, struct old_method_list *mlist, struct old_category *cat);
330 extern void _objc_removeMethods(Class cls, struct old_method_list *mlist);
331 extern void _objc_flush_caches (Class cls);
332 extern bool _class_addProperties(Class cls, struct old_property_list *additions);
333 extern bool _class_hasLoadMethod(Class cls);
334 extern void change_class_references(Class imposter, Class original, Class copy, bool changeSuperRefs);
335 extern void flush_marked_caches(void);
336 extern void set_superclass(Class cls, Class supercls, bool cls_is_new);
337 extern void try_free(const void *p);
338
339 extern struct old_property *property_list_nth(const struct old_property_list *plist, uint32_t i);
340 extern struct old_property **copyPropertyList(struct old_property_list *plist, unsigned int *outCount);
341
342 extern struct objc_method_description * lookup_protocol_method(struct old_protocol *proto, SEL aSel, bool isRequiredMethod, bool isInstanceMethod, bool recursive);
343
344 // used by flush_caches outside objc-cache.m
345 extern void _cache_flush(Class cls);
346 #ifdef OBJC_INSTRUMENTED
347 extern unsigned int LinearFlushCachesCount;
348 extern unsigned int LinearFlushCachesVisitedCount;
349 extern unsigned int MaxLinearFlushCachesVisitedCount;
350 extern unsigned int NonlinearFlushCachesCount;
351 extern unsigned int NonlinearFlushCachesClassCount;
352 extern unsigned int NonlinearFlushCachesVisitedCount;
353 extern unsigned int MaxNonlinearFlushCachesVisitedCount;
354 extern unsigned int IdealFlushCachesCount;
355 extern unsigned int MaxIdealFlushCachesCount;
356 #endif
357
358 __END_DECLS
359
360 #endif