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