123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550 |
- /*
- * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
- /*
- Object.m
- Copyright 1988-1996 NeXT Software, Inc.
- */
- #include "objc-private.h"
- #undef id
- #undef Class
- typedef struct objc_class *Class;
- typedef struct objc_object *id;
- #if __OBJC2__
- @implementation Object
- + (id)initialize
- {
- return self;
- }
- + (id)class
- {
- return self;
- }
- -(id) retain
- {
- return _objc_rootRetain(self);
- }
- -(void) release
- {
- _objc_rootRelease(self);
- }
- -(id) autorelease
- {
- return _objc_rootAutorelease(self);
- }
- +(id) retain
- {
- return self;
- }
- +(void) release
- {
- }
- +(id) autorelease
- {
- return self;
- }
- @end
- // __OBJC2__
- #else
- // not __OBJC2__
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include <malloc/malloc.h>
- #include "Object.h"
- #include "Protocol.h"
- #include "objc-runtime.h"
- // Error Messages
- static const char
- _errShouldHaveImp[] = "should have implemented the '%s' method.",
- _errShouldNotImp[] = "should NOT have implemented the '%s' method.",
- _errLeftUndone[] = "method '%s' not implemented",
- _errBadSel[] = "method %s given invalid selector %s",
- _errDoesntRecognize[] = "does not recognize selector %c%s";
- @implementation Object
- + (id)initialize
- {
- return self;
- }
- - (id)awake
- {
- return self;
- }
- + (id)poseAs: aFactory
- {
- return class_poseAs(self, aFactory);
- }
- + (id)new
- {
- id newObject = (*_alloc)((Class)self, 0);
- Class metaClass = self->ISA();
- if (class_getVersion(metaClass) > 1)
- return [newObject init];
- else
- return newObject;
- }
- + (id)alloc
- {
- return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
- }
- + (id)allocFromZone:(void *) z
- {
- return (*_zoneAlloc)((Class)self, 0, z);
- }
- - (id)init
- {
- return self;
- }
- - (const char *)name
- {
- return class_getName(isa);
- }
- + (const char *)name
- {
- return class_getName((Class)self);
- }
- - (unsigned)hash
- {
- return (unsigned)(((uintptr_t)self) >> 2);
- }
- - (BOOL)isEqual:anObject
- {
- return anObject == self;
- }
- - (id)free
- {
- return (*_dealloc)(self);
- }
- + (id)free
- {
- return nil;
- }
- - (id)self
- {
- return self;
- }
- -(id)class
- {
- return (id)isa;
- }
- + (id)class
- {
- return self;
- }
- - (void *)zone
- {
- void *z = malloc_zone_from_ptr(self);
- return z ? z : malloc_default_zone();
- }
- + (id)superclass
- {
- return self->superclass;
- }
- - (id)superclass
- {
- return isa->superclass;
- }
- + (int) version
- {
- return class_getVersion((Class)self);
- }
- + (id)setVersion: (int) aVersion
- {
- class_setVersion((Class)self, aVersion);
- return self;
- }
- - (BOOL)isKindOf:aClass
- {
- Class cls;
- for (cls = isa; cls; cls = cls->superclass)
- if (cls == (Class)aClass)
- return YES;
- return NO;
- }
- - (BOOL)isMemberOf:aClass
- {
- return isa == (Class)aClass;
- }
- - (BOOL)isKindOfClassNamed:(const char *)aClassName
- {
- Class cls;
- for (cls = isa; cls; cls = cls->superclass)
- if (strcmp(aClassName, class_getName(cls)) == 0)
- return YES;
- return NO;
- }
- - (BOOL)isMemberOfClassNamed:(const char *)aClassName
- {
- return strcmp(aClassName, class_getName(isa)) == 0;
- }
- + (BOOL)instancesRespondTo:(SEL)aSelector
- {
- return class_respondsToMethod((Class)self, aSelector);
- }
- - (BOOL)respondsTo:(SEL)aSelector
- {
- return class_respondsToMethod(isa, aSelector);
- }
- - (id)copy
- {
- return [self copyFromZone: [self zone]];
- }
- - (id)copyFromZone:(void *)z
- {
- return (*_zoneCopy)(self, 0, z);
- }
- - (IMP)methodFor:(SEL)aSelector
- {
- return class_lookupMethod(isa, aSelector);
- }
- + (IMP)instanceMethodFor:(SEL)aSelector
- {
- return class_lookupMethod(self, aSelector);
- }
- - (id)perform:(SEL)aSelector
- {
- if (aSelector)
- return ((id(*)(id, SEL))objc_msgSend)(self, aSelector);
- else
- return [self error:_errBadSel, sel_getName(_cmd), aSelector];
- }
- - (id)perform:(SEL)aSelector with:anObject
- {
- if (aSelector)
- return ((id(*)(id, SEL, id))objc_msgSend)(self, aSelector, anObject);
- else
- return [self error:_errBadSel, sel_getName(_cmd), aSelector];
- }
- - (id)perform:(SEL)aSelector with:obj1 with:obj2
- {
- if (aSelector)
- return ((id(*)(id, SEL, id, id))objc_msgSend)(self, aSelector, obj1, obj2);
- else
- return [self error:_errBadSel, sel_getName(_cmd), aSelector];
- }
- - (id)subclassResponsibility:(SEL)aSelector
- {
- return [self error:_errShouldHaveImp, sel_getName(aSelector)];
- }
- - (id)notImplemented:(SEL)aSelector
- {
- return [self error:_errLeftUndone, sel_getName(aSelector)];
- }
- - (id)doesNotRecognize:(SEL)aMessage
- {
- return [self error:_errDoesntRecognize,
- class_isMetaClass(isa) ? '+' : '-', sel_getName(aMessage)];
- }
- - (id)error:(const char *)aCStr, ...
- {
- va_list ap;
- va_start(ap,aCStr);
- (*_error)(self, aCStr, ap);
- _objc_error (self, aCStr, ap); /* In case (*_error)() returns. */
- va_end(ap);
- return nil;
- }
- - (void) printForDebugger:(void *)stream
- {
- }
- - (id)write:(void *) stream
- {
- return self;
- }
- - (id)read:(void *) stream
- {
- return self;
- }
- - (id)forward: (SEL) sel : (marg_list) args
- {
- return [self doesNotRecognize: sel];
- }
- /* this method is not part of the published API */
- - (unsigned)methodArgSize:(SEL)sel
- {
- Method method = class_getInstanceMethod((Class)isa, sel);
- if (! method) return 0;
- return method_getSizeOfArguments(method);
- }
- - (id)performv: (SEL) sel : (marg_list) args
- {
- unsigned size;
- // Messages to nil object always return nil
- if (! self) return nil;
- // Calculate size of the marg_list from the method's
- // signature. This looks for the method in self
- // and its superclasses.
- size = [self methodArgSize: sel];
- // If neither self nor its superclasses implement
- // it, forward the message because self might know
- // someone who does. This is a "chained" forward...
- if (! size) return [self forward: sel: args];
- // Message self with the specified selector and arguments
- return objc_msgSendv (self, sel, size, args);
- }
- /* Testing protocol conformance */
- - (BOOL) conformsTo: (Protocol *)aProtocolObj
- {
- return [(id)isa conformsTo:aProtocolObj];
- }
- + (BOOL) conformsTo: (Protocol *)aProtocolObj
- {
- Class cls;
- for (cls = self; cls; cls = cls->superclass)
- {
- if (class_conformsToProtocol(cls, aProtocolObj)) return YES;
- }
- return NO;
- }
- /* Looking up information for a method */
- - (struct objc_method_description *) descriptionForMethod:(SEL)aSelector
- {
- Class cls;
- struct objc_method_description *m;
- /* Look in the protocols first. */
- for (cls = isa; cls; cls = cls->superclass)
- {
- if (cls->ISA()->version >= 3)
- {
- struct objc_protocol_list *protocols =
- (struct objc_protocol_list *)cls->protocols;
-
- while (protocols)
- {
- int i;
- for (i = 0; i < protocols->count; i++)
- {
- Protocol *p = protocols->list[i];
- if (class_isMetaClass(cls))
- m = [p descriptionForClassMethod:aSelector];
- else
- m = [p descriptionForInstanceMethod:aSelector];
- if (m) {
- return m;
- }
- }
-
- if (cls->ISA()->version <= 4)
- break;
-
- protocols = protocols->next;
- }
- }
- }
- /* Then try the class implementations. */
- for (cls = isa; cls; cls = cls->superclass) {
- void *iterator = 0;
- int i;
- struct objc_method_list *mlist;
- while ( (mlist = class_nextMethodList( cls, &iterator )) ) {
- for (i = 0; i < mlist->method_count; i++)
- if (mlist->method_list[i].method_name == aSelector) {
- m = (struct objc_method_description *)&mlist->method_list[i];
- return m;
- }
- }
- }
- return 0;
- }
- + (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSelector
- {
- Class cls;
- /* Look in the protocols first. */
- for (cls = self; cls; cls = cls->superclass)
- {
- if (cls->ISA()->version >= 3)
- {
- struct objc_protocol_list *protocols =
- (struct objc_protocol_list *)cls->protocols;
-
- while (protocols)
- {
- int i;
- for (i = 0; i < protocols->count; i++)
- {
- Protocol *p = protocols->list[i];
- struct objc_method_description *m;
- if ((m = [p descriptionForInstanceMethod:aSelector]))
- return m;
- }
-
- if (cls->ISA()->version <= 4)
- break;
-
- protocols = protocols->next;
- }
- }
- }
- /* Then try the class implementations. */
- for (cls = self; cls; cls = cls->superclass) {
- void *iterator = 0;
- int i;
- struct objc_method_list *mlist;
- while ( (mlist = class_nextMethodList( cls, &iterator )) ) {
- for (i = 0; i < mlist->method_count; i++)
- if (mlist->method_list[i].method_name == aSelector) {
- struct objc_method_description *m;
- m = (struct objc_method_description *)&mlist->method_list[i];
- return m;
- }
- }
- }
- return 0;
- }
- /* Obsolete methods (for binary compatibility only). */
- + (id)superClass
- {
- return [self superclass];
- }
- - (id)superClass
- {
- return [self superclass];
- }
- - (BOOL)isKindOfGivenName:(const char *)aClassName
- {
- return [self isKindOfClassNamed: aClassName];
- }
- - (BOOL)isMemberOfGivenName:(const char *)aClassName
- {
- return [self isMemberOfClassNamed: aClassName];
- }
- - (struct objc_method_description *) methodDescFor:(SEL)aSelector
- {
- return [self descriptionForMethod: aSelector];
- }
- + (struct objc_method_description *) instanceMethodDescFor:(SEL)aSelector
- {
- return [self descriptionForInstanceMethod: aSelector];
- }
- - (id)findClass:(const char *)aClassName
- {
- return objc_lookUpClass(aClassName);
- }
- - (id)shouldNotImplement:(SEL)aSelector
- {
- return [self error:_errShouldNotImp, sel_getName(aSelector)];
- }
- @end
- #endif
|