]> git.saurik.com Git - apple/objc4.git/blob - runtime/Object.m
objc4-437.tar.gz
[apple/objc4.git] / runtime / Object.m
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 Object.m
25 Copyright 1988-1996 NeXT Software, Inc.
26 */
27
28 #if __OBJC2__
29
30 #import "Object.h"
31
32 @implementation Object
33
34 + initialize
35 {
36 return self;
37 }
38
39 + class
40 {
41 return self;
42 }
43
44 @end
45
46 #else
47
48 #import <stdlib.h>
49 #import <stdarg.h>
50 #import <string.h>
51 #import <malloc/malloc.h>
52
53 #define OLD 1
54 #import "Object.h"
55 #import "Protocol.h"
56 #import "objc-runtime.h"
57 #import "objc-auto.h"
58
59 // hack
60 extern void _objc_error(id, const char *, va_list);
61
62
63 // Error Messages
64 static const char
65 _errShouldHaveImp[] = "should have implemented the '%s' method.",
66 _errShouldNotImp[] = "should NOT have implemented the '%s' method.",
67 _errLeftUndone[] = "method '%s' not implemented",
68 _errBadSel[] = "method %s given invalid selector %s",
69 _errDoesntRecognize[] = "does not recognize selector %c%s";
70
71
72 @implementation Object
73
74
75 + initialize
76 {
77 return self;
78 }
79
80 - awake
81 {
82 return self;
83 }
84
85 + poseAs: aFactory
86 {
87 return class_poseAs(self, aFactory);
88 }
89
90 + new
91 {
92 id newObject = (*_alloc)((Class)self, 0);
93 Class metaClass = self->isa;
94 if (class_getVersion(metaClass) > 1)
95 return [newObject init];
96 else
97 return newObject;
98 }
99
100 + alloc
101 {
102 return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
103 }
104
105 + allocFromZone:(void *) z
106 {
107 return (*_zoneAlloc)((Class)self, 0, z);
108 }
109
110 - init
111 {
112 return self;
113 }
114
115 - (const char *)name
116 {
117 return class_getName(isa);
118 }
119
120 + (const char *)name
121 {
122 return class_getName((Class)self);
123 }
124
125 - (unsigned)hash
126 {
127 return (unsigned)(((uintptr_t)self) >> 2);
128 }
129
130 - (BOOL)isEqual:anObject
131 {
132 return anObject == self;
133 }
134
135 - free
136 {
137 return (*_dealloc)(self);
138 }
139
140 + free
141 {
142 return nil;
143 }
144
145 - self
146 {
147 return self;
148 }
149
150 - class
151 {
152 return (id)isa;
153 }
154
155 + class
156 {
157 return self;
158 }
159
160 - (void *)zone
161 {
162 void *z = malloc_zone_from_ptr(self);
163 return z ? z : malloc_default_zone();
164 }
165
166 + superclass
167 {
168 return class_getSuperclass((Class)self);
169 }
170
171 - superclass
172 {
173 return class_getSuperclass(isa);
174 }
175
176 + (int) version
177 {
178 return class_getVersion((Class)self);
179 }
180
181 + setVersion: (int) aVersion
182 {
183 class_setVersion((Class)self, aVersion);
184 return self;
185 }
186
187 - (BOOL)isKindOf:aClass
188 {
189 register Class cls;
190 for (cls = isa; cls; cls = class_getSuperclass(cls))
191 if (cls == (Class)aClass)
192 return YES;
193 return NO;
194 }
195
196 - (BOOL)isMemberOf:aClass
197 {
198 return isa == (Class)aClass;
199 }
200
201 - (BOOL)isKindOfClassNamed:(const char *)aClassName
202 {
203 register Class cls;
204 for (cls = isa; cls; cls = class_getSuperclass(cls))
205 if (strcmp(aClassName, class_getName(cls)) == 0)
206 return YES;
207 return NO;
208 }
209
210 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
211 {
212 return strcmp(aClassName, class_getName(isa)) == 0;
213 }
214
215 + (BOOL)instancesRespondTo:(SEL)aSelector
216 {
217 return class_respondsToMethod((Class)self, aSelector);
218 }
219
220 - (BOOL)respondsTo:(SEL)aSelector
221 {
222 return class_respondsToMethod(isa, aSelector);
223 }
224
225 - copy
226 {
227 return [self copyFromZone: [self zone]];
228 }
229
230 - copyFromZone:(void *)z
231 {
232 return (*_zoneCopy)(self, 0, z);
233 }
234
235 - (IMP)methodFor:(SEL)aSelector
236 {
237 return class_lookupMethod(isa, aSelector);
238 }
239
240 + (IMP)instanceMethodFor:(SEL)aSelector
241 {
242 return class_lookupMethod(self, aSelector);
243 }
244
245 - perform:(SEL)aSelector
246 {
247 if (aSelector)
248 return objc_msgSend(self, aSelector);
249 else
250 return [self error:_errBadSel, sel_getName(_cmd), aSelector];
251 }
252
253 - perform:(SEL)aSelector with:anObject
254 {
255 if (aSelector)
256 return objc_msgSend(self, aSelector, anObject);
257 else
258 return [self error:_errBadSel, sel_getName(_cmd), aSelector];
259 }
260
261 - perform:(SEL)aSelector with:obj1 with:obj2
262 {
263 if (aSelector)
264 return objc_msgSend(self, aSelector, obj1, obj2);
265 else
266 return [self error:_errBadSel, sel_getName(_cmd), aSelector];
267 }
268
269 - subclassResponsibility:(SEL)aSelector
270 {
271 return [self error:_errShouldHaveImp, sel_getName(aSelector)];
272 }
273
274 - notImplemented:(SEL)aSelector
275 {
276 return [self error:_errLeftUndone, sel_getName(aSelector)];
277 }
278
279 - doesNotRecognize:(SEL)aMessage
280 {
281 return [self error:_errDoesntRecognize,
282 class_isMetaClass(isa) ? '+' : '-', sel_getName(aMessage)];
283 }
284
285 - error:(const char *)aCStr, ...
286 {
287 va_list ap;
288 va_start(ap,aCStr);
289 (*_error)(self, aCStr, ap);
290 _objc_error (self, aCStr, ap); /* In case (*_error)() returns. */
291 va_end(ap);
292 return nil;
293 }
294
295 - (void) printForDebugger:(void *)stream
296 {
297 }
298
299 - write:(void *) stream
300 {
301 return self;
302 }
303
304 - read:(void *) stream
305 {
306 return self;
307 }
308
309 - forward: (SEL) sel : (marg_list) args
310 {
311 return [self doesNotRecognize: sel];
312 }
313
314 /* this method is not part of the published API */
315
316 - (unsigned)methodArgSize:(SEL)sel
317 {
318 Method method = class_getInstanceMethod((Class)isa, sel);
319 if (! method) return 0;
320 return method_getSizeOfArguments(method);
321 }
322
323 - performv: (SEL) sel : (marg_list) args
324 {
325 unsigned size;
326
327 // Messages to nil object always return nil
328 if (! self) return nil;
329
330 // Calculate size of the marg_list from the method's
331 // signature. This looks for the method in self
332 // and its superclasses.
333 size = [self methodArgSize: sel];
334
335 // If neither self nor its superclasses implement
336 // it, forward the message because self might know
337 // someone who does. This is a "chained" forward...
338 if (! size) return [self forward: sel: args];
339
340 // Message self with the specified selector and arguments
341 return objc_msgSendv (self, sel, size, args);
342 }
343
344 /* Testing protocol conformance */
345
346 - (BOOL) conformsTo: (Protocol *)aProtocolObj
347 {
348 return [(id)isa conformsTo:aProtocolObj];
349 }
350
351 + (BOOL) conformsTo: (Protocol *)aProtocolObj
352 {
353 Class class;
354 for (class = self; class; class = class_getSuperclass(class))
355 {
356 if (class_conformsToProtocol(class, aProtocolObj)) return YES;
357 }
358 return NO;
359 }
360
361
362 /* Looking up information for a method */
363
364 - (struct objc_method_description *) descriptionForMethod:(SEL)aSelector
365 {
366 Class cls;
367 struct objc_method_description *m;
368
369 /* Look in the protocols first. */
370 for (cls = isa; cls; cls = cls->super_class)
371 {
372 if (cls->isa->version >= 3)
373 {
374 struct objc_protocol_list *protocols = cls->protocols;
375
376 while (protocols)
377 {
378 int i;
379
380 for (i = 0; i < protocols->count; i++)
381 {
382 Protocol *p = protocols->list[i];
383
384 if (class_isMetaClass(cls))
385 m = [p descriptionForClassMethod:aSelector];
386 else
387 m = [p descriptionForInstanceMethod:aSelector];
388
389 if (m) {
390 return m;
391 }
392 }
393
394 if (cls->isa->version <= 4)
395 break;
396
397 protocols = protocols->next;
398 }
399 }
400 }
401
402 /* Then try the class implementations. */
403 for (cls = isa; cls; cls = cls->super_class) {
404 void *iterator = 0;
405 int i;
406 struct objc_method_list *mlist;
407 while ( (mlist = class_nextMethodList( cls, &iterator )) ) {
408 for (i = 0; i < mlist->method_count; i++)
409 if (mlist->method_list[i].method_name == aSelector) {
410 struct objc_method_description *m;
411 m = (struct objc_method_description *)&mlist->method_list[i];
412 return m;
413 }
414 }
415 }
416 return 0;
417 }
418
419 + (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSelector
420 {
421 Class cls;
422
423 /* Look in the protocols first. */
424 for (cls = self; cls; cls = cls->super_class)
425 {
426 if (cls->isa->version >= 3)
427 {
428 struct objc_protocol_list *protocols = cls->protocols;
429
430 while (protocols)
431 {
432 int i;
433
434 for (i = 0; i < protocols->count; i++)
435 {
436 Protocol *p = protocols->list[i];
437 struct objc_method_description *m;
438
439 if ((m = [p descriptionForInstanceMethod:aSelector]))
440 return m;
441 }
442
443 if (cls->isa->version <= 4)
444 break;
445
446 protocols = protocols->next;
447 }
448 }
449 }
450
451 /* Then try the class implementations. */
452 for (cls = self; cls; cls = cls->super_class) {
453 void *iterator = 0;
454 int i;
455 struct objc_method_list *mlist;
456 while ( (mlist = class_nextMethodList( cls, &iterator )) ) {
457 for (i = 0; i < mlist->method_count; i++)
458 if (mlist->method_list[i].method_name == aSelector) {
459 struct objc_method_description *m;
460 m = (struct objc_method_description *)&mlist->method_list[i];
461 return m;
462 }
463 }
464 }
465 return 0;
466 }
467
468
469 /* Obsolete methods (for binary compatibility only). */
470
471 + superClass
472 {
473 return [self superclass];
474 }
475
476 - superClass
477 {
478 return [self superclass];
479 }
480
481 - (BOOL)isKindOfGivenName:(const char *)aClassName
482 {
483 return [self isKindOfClassNamed: aClassName];
484 }
485
486 - (BOOL)isMemberOfGivenName:(const char *)aClassName
487 {
488 return [self isMemberOfClassNamed: aClassName];
489 }
490
491 - (struct objc_method_description *) methodDescFor:(SEL)aSelector
492 {
493 return [self descriptionForMethod: aSelector];
494 }
495
496 + (struct objc_method_description *) instanceMethodDescFor:(SEL)aSelector
497 {
498 return [self descriptionForInstanceMethod: aSelector];
499 }
500
501 - findClass:(const char *)aClassName
502 {
503 return objc_lookUpClass(aClassName);
504 }
505
506 - shouldNotImplement:(SEL)aSelector
507 {
508 return [self error:_errShouldNotImp, sel_getName(aSelector)];
509 }
510
511
512 @end
513
514 #endif