2 * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 Copyright 1988-1996 NeXT Software, Inc.
28 #include "objc-private.h"
33 typedef struct objc_class *Class;
34 typedef struct objc_object *id;
39 __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE
46 @implementation Object
60 return _objc_rootRetain(self);
65 _objc_rootRelease(self);
70 return _objc_rootAutorelease(self);
98 #include <malloc/malloc.h>
101 #include "Protocol.h"
102 #include "objc-runtime.h"
107 _errShouldHaveImp[] = "should have implemented the '%s' method.",
108 _errShouldNotImp[] = "should NOT have implemented the '%s' method.",
109 _errLeftUndone[] = "method '%s' not implemented",
110 _errBadSel[] = "method %s given invalid selector %s",
111 _errDoesntRecognize[] = "does not recognize selector %c%s";
114 @implementation Object
127 + (id)poseAs: aFactory
129 return class_poseAs(self, aFactory);
134 id newObject = (*_alloc)((Class)self, 0);
135 Class metaClass = self->ISA();
136 if (class_getVersion(metaClass) > 1)
137 return [newObject init];
144 return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
147 + (id)allocFromZone:(void *) z
149 return (*_zoneAlloc)((Class)self, 0, z);
159 return class_getName(isa);
164 return class_getName((Class)self);
169 return (unsigned)(((uintptr_t)self) >> 2);
172 - (BOOL)isEqual:anObject
174 return anObject == self;
179 return (*_dealloc)(self);
205 void *z = malloc_zone_from_ptr(self);
206 return z ? z : malloc_default_zone();
211 return self->superclass;
216 return isa->superclass;
221 return class_getVersion((Class)self);
224 + (id)setVersion: (int) aVersion
226 class_setVersion((Class)self, aVersion);
230 - (BOOL)isKindOf:aClass
233 for (cls = isa; cls; cls = cls->superclass)
234 if (cls == (Class)aClass)
239 - (BOOL)isMemberOf:aClass
241 return isa == (Class)aClass;
244 - (BOOL)isKindOfClassNamed:(const char *)aClassName
247 for (cls = isa; cls; cls = cls->superclass)
248 if (strcmp(aClassName, class_getName(cls)) == 0)
253 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
255 return strcmp(aClassName, class_getName(isa)) == 0;
258 + (BOOL)instancesRespondTo:(SEL)aSelector
260 return class_respondsToMethod((Class)self, aSelector);
263 - (BOOL)respondsTo:(SEL)aSelector
265 return class_respondsToMethod(isa, aSelector);
270 return [self copyFromZone: [self zone]];
273 - (id)copyFromZone:(void *)z
275 return (*_zoneCopy)(self, 0, z);
278 - (IMP)methodFor:(SEL)aSelector
280 return class_lookupMethod(isa, aSelector);
283 + (IMP)instanceMethodFor:(SEL)aSelector
285 return class_lookupMethod(self, aSelector);
288 - (id)perform:(SEL)aSelector
291 return ((id(*)(id, SEL))objc_msgSend)(self, aSelector);
293 return [self error:_errBadSel, sel_getName(_cmd), aSelector];
296 - (id)perform:(SEL)aSelector with:anObject
299 return ((id(*)(id, SEL, id))objc_msgSend)(self, aSelector, anObject);
301 return [self error:_errBadSel, sel_getName(_cmd), aSelector];
304 - (id)perform:(SEL)aSelector with:obj1 with:obj2
307 return ((id(*)(id, SEL, id, id))objc_msgSend)(self, aSelector, obj1, obj2);
309 return [self error:_errBadSel, sel_getName(_cmd), aSelector];
312 - (id)subclassResponsibility:(SEL)aSelector
314 return [self error:_errShouldHaveImp, sel_getName(aSelector)];
317 - (id)notImplemented:(SEL)aSelector
319 return [self error:_errLeftUndone, sel_getName(aSelector)];
322 - (id)doesNotRecognize:(SEL)aMessage
324 return [self error:_errDoesntRecognize,
325 class_isMetaClass(isa) ? '+' : '-', sel_getName(aMessage)];
328 - (id)error:(const char *)aCStr, ...
332 (*_error)(self, aCStr, ap);
333 _objc_error (self, aCStr, ap); /* In case (*_error)() returns. */
338 - (void) printForDebugger:(void *)stream
342 - (id)write:(void *) stream
347 - (id)read:(void *) stream
352 - (id)forward: (SEL) sel : (marg_list) args
354 return [self doesNotRecognize: sel];
357 /* this method is not part of the published API */
359 - (unsigned)methodArgSize:(SEL)sel
361 Method method = class_getInstanceMethod((Class)isa, sel);
362 if (! method) return 0;
363 return method_getSizeOfArguments(method);
366 - (id)performv: (SEL) sel : (marg_list) args
370 // Messages to nil object always return nil
371 if (! self) return nil;
373 // Calculate size of the marg_list from the method's
374 // signature. This looks for the method in self
375 // and its superclasses.
376 size = [self methodArgSize: sel];
378 // If neither self nor its superclasses implement
379 // it, forward the message because self might know
380 // someone who does. This is a "chained" forward...
381 if (! size) return [self forward: sel: args];
383 // Message self with the specified selector and arguments
384 return objc_msgSendv (self, sel, size, args);
387 /* Testing protocol conformance */
389 - (BOOL) conformsTo: (Protocol *)aProtocolObj
391 return [(id)isa conformsTo:aProtocolObj];
394 + (BOOL) conformsTo: (Protocol *)aProtocolObj
397 for (cls = self; cls; cls = cls->superclass)
399 if (class_conformsToProtocol(cls, aProtocolObj)) return YES;
405 /* Looking up information for a method */
407 - (struct objc_method_description *) descriptionForMethod:(SEL)aSelector
410 struct objc_method_description *m;
412 /* Look in the protocols first. */
413 for (cls = isa; cls; cls = cls->superclass)
415 if (cls->ISA()->version >= 3)
417 struct objc_protocol_list *protocols =
418 (struct objc_protocol_list *)cls->protocols;
424 for (i = 0; i < protocols->count; i++)
426 Protocol *p = protocols->list[i];
428 if (class_isMetaClass(cls))
429 m = [p descriptionForClassMethod:aSelector];
431 m = [p descriptionForInstanceMethod:aSelector];
438 if (cls->ISA()->version <= 4)
441 protocols = protocols->next;
446 /* Then try the class implementations. */
447 for (cls = isa; cls; cls = cls->superclass) {
450 struct objc_method_list *mlist;
451 while ( (mlist = class_nextMethodList( cls, &iterator )) ) {
452 for (i = 0; i < mlist->method_count; i++)
453 if (mlist->method_list[i].method_name == aSelector) {
454 m = (struct objc_method_description *)&mlist->method_list[i];
462 + (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSelector
466 /* Look in the protocols first. */
467 for (cls = self; cls; cls = cls->superclass)
469 if (cls->ISA()->version >= 3)
471 struct objc_protocol_list *protocols =
472 (struct objc_protocol_list *)cls->protocols;
478 for (i = 0; i < protocols->count; i++)
480 Protocol *p = protocols->list[i];
481 struct objc_method_description *m;
483 if ((m = [p descriptionForInstanceMethod:aSelector]))
487 if (cls->ISA()->version <= 4)
490 protocols = protocols->next;
495 /* Then try the class implementations. */
496 for (cls = self; cls; cls = cls->superclass) {
499 struct objc_method_list *mlist;
500 while ( (mlist = class_nextMethodList( cls, &iterator )) ) {
501 for (i = 0; i < mlist->method_count; i++)
502 if (mlist->method_list[i].method_name == aSelector) {
503 struct objc_method_description *m;
504 m = (struct objc_method_description *)&mlist->method_list[i];
513 /* Obsolete methods (for binary compatibility only). */
517 return [self superclass];
522 return [self superclass];
525 - (BOOL)isKindOfGivenName:(const char *)aClassName
527 return [self isKindOfClassNamed: aClassName];
530 - (BOOL)isMemberOfGivenName:(const char *)aClassName
532 return [self isMemberOfClassNamed: aClassName];
535 - (struct objc_method_description *) methodDescFor:(SEL)aSelector
537 return [self descriptionForMethod: aSelector];
540 + (struct objc_method_description *) instanceMethodDescFor:(SEL)aSelector
542 return [self descriptionForInstanceMethod: aSelector];
545 - (id)findClass:(const char *)aClassName
547 return objc_lookUpClass(aClassName);
550 - (id)shouldNotImplement:(SEL)aSelector
552 return [self error:_errShouldNotImp, sel_getName(aSelector)];