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