2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
27 Copyright 1988-1996 NeXT Software, Inc.
30 #import <objc/Object.h>
31 #import "objc-private.h"
32 #import <objc/objc-auto.h>
33 #import <objc/objc-runtime.h>
34 #import <objc/Protocol.h>
38 OBJC_EXPORT id (*_cvtToId)(const char *);
39 OBJC_EXPORT id (*_poseAs)();
44 _errNoMem[] = "failed -- out of memory(%s, %u)",
45 _errReAllocNil[] = "reallocating nil object",
46 _errReAllocFreed[] = "reallocating freed object",
47 _errReAllocTooSmall[] = "(%s, %u) requested size too small",
48 _errShouldHaveImp[] = "should have implemented the '%s' method.",
49 _errShouldNotImp[] = "should NOT have implemented the '%s' method.",
50 _errLeftUndone[] = "method '%s' not implemented",
51 _errBadSel[] = "method %s given invalid selector %s",
52 _errDoesntRecognize[] = "does not recognize selector %c%s";
55 @implementation Object
70 return (*_poseAs)(self, aFactory);
75 id newObject = (*_alloc)((Class)self, 0);
76 struct objc_class * metaClass = ((struct objc_class *) self)->isa;
77 if (metaClass->version > 1)
78 return [newObject init];
85 return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
88 + allocFromZone:(void *) z
90 return (*_zoneAlloc)((Class)self, 0, z);
100 return ((struct objc_class *)isa)->name;
105 return ((struct objc_class *)self)->name;
110 return ((uarith_t)self) >> 2;
113 - (BOOL)isEqual:anObject
115 return anObject == self;
120 return (*_dealloc)(self);
145 void *z = malloc_zone_from_ptr(self);
146 return z ? z : malloc_default_zone();
151 return ((struct objc_class *)self)->super_class;
156 return ((struct objc_class *)isa)->super_class;
161 struct objc_class * class = (struct objc_class *) self;
162 return class->version;
165 + setVersion: (int) aVersion
167 struct objc_class * class = (struct objc_class *) self;
168 class->version = aVersion;
172 - (BOOL)isKindOf:aClass
175 for (cls = isa; cls; cls = ((struct objc_class *)cls)->super_class)
176 if (cls == (Class)aClass)
181 - (BOOL)isMemberOf:aClass
183 return isa == (Class)aClass;
186 - (BOOL)isKindOfClassNamed:(const char *)aClassName
189 for (cls = isa; cls; cls = ((struct objc_class *)cls)->super_class)
190 if (strcmp(aClassName, ((struct objc_class *)cls)->name) == 0)
195 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
197 return strcmp(aClassName, ((struct objc_class *)isa)->name) == 0;
200 + (BOOL)instancesRespondTo:(SEL)aSelector
202 return class_respondsToMethod((Class)self, aSelector);
205 - (BOOL)respondsTo:(SEL)aSelector
207 return class_respondsToMethod(isa, aSelector);
212 return [self copyFromZone: [self zone]];
215 - copyFromZone:(void *)z
217 return (*_zoneCopy)(self, 0, z);
220 - (IMP)methodFor:(SEL)aSelector
222 return class_lookupMethod(isa, aSelector);
225 + (IMP)instanceMethodFor:(SEL)aSelector
227 return class_lookupMethod(self, aSelector);
230 #if defined(__alpha__)
231 #define MAX_RETSTRUCT_SIZE 256
233 typedef struct _foolGCC {
234 char c[MAX_RETSTRUCT_SIZE];
237 typedef _variableStruct (*callReturnsStruct)();
239 OBJC_EXPORT long sizeOfReturnedStruct(char **);
241 long sizeOfType(char **pp)
244 long stack_size = 0, n = 0;
248 stack_size += sizeof(char); // Alignment ?
252 stack_size += sizeof(short);// Alignment ?
257 stack_size += sizeof(int);
261 stack_size += sizeof(long int);
264 stack_size += sizeof(float);
267 stack_size += sizeof(double);
273 stack_size += sizeof(char*);
276 stack_size += sizeOfReturnedStruct(&p);
282 n = 10 * n + (*p++ - '0');
283 stack_size += (n * sizeOfType(&p));
293 sizeOfReturnedStruct(char **pp)
296 long stack_size = 0, n = 0;
297 while(p!=NULL && *++p!='=') ; // skip the struct name
298 while(p!=NULL && *++p!='}')
299 stack_size += sizeOfType(&p);
300 return stack_size + 8; // Add 8 as a 'forfait value'
301 // to take alignment into account
304 - perform:(SEL)aSelector
308 _variableStruct *dummyRetVal;
312 method = class_getInstanceMethod((Class)self->isa,
315 method = class_getClassMethod((Class)self->isa,
318 p = &method->method_types[0];
320 // Method returns a structure
321 stack_size = sizeOfReturnedStruct(&p);
322 if(stack_size<MAX_RETSTRUCT_SIZE)
325 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
326 // return structures whose size is not grater than
327 // MAX_RETSTRUCT_SIZE.
328 // This is because the compiler allocates space on the stack
329 // for the size of the return structure, and when the method
330 // returns, the structure is copied on the space allocated
331 // on the stack: if the structure is greater than the space
332 // allocated... bang! (the stack is gone:-)
334 ((callReturnsStruct)objc_msgSend)(self, aSelector);
338 dummyRetVal = (_variableStruct*) malloc(stack_size);
340 // Following asm code is equivalent to:
341 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector);
343 asm("ldq $16,%0":"=g" (dummyRetVal):);
344 asm("ldq $17,%0":"=g" (self):);
345 asm("ldq $18,%0":"=g" (aSelector):);
346 asm("bis $31,1,$25");
347 asm("lda $27,objc_msgSend");
348 asm("jsr $26,($27),objc_msgSend");
349 asm("ldgp $29,0($26)");
351 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector);
355 // When the method return a structure, we cannot return it here
356 // becuse we're not called in the right way, so we must return
357 // something else: wether it is self or NULL is a matter of taste.
361 // We fall back here either because the method doesn't return
362 // a structure, or because method is NULL: in this latter
363 // case the call to msgSend will try to forward the message.
364 return objc_msgSend(self, aSelector);
367 // We fallback here only when aSelector is NULL
368 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
371 - perform:(SEL)aSelector with:anObject
375 _variableStruct *dummyRetVal;
379 method = class_getInstanceMethod((Class)self->isa,
382 method = class_getClassMethod((Class)self->isa,
385 p = &method->method_types[0];
387 // Method returns a structure
388 stack_size = sizeOfReturnedStruct(&p);
389 if(stack_size<MAX_RETSTRUCT_SIZE)
392 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
393 // return structures whose size is not grater than
394 // MAX_RETSTRUCT_SIZE.
395 // This is because the compiler allocates space on the stack
396 // for the size of the return structure, and when the method
397 // returns, the structure is copied on the space allocated
398 // on the stack: if the structure is greater than the space
399 // allocated... bang! (the stack is gone:-)
401 ((callReturnsStruct)objc_msgSend)(self, aSelector, anObject);
405 dummyRetVal = (_variableStruct*) malloc(stack_size);
407 // Following asm code is equivalent to:
408 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,anObject);
410 asm("ldq $16,%0":"=g" (dummyRetVal):);
411 asm("ldq $17,%0":"=g" (self):);
412 asm("ldq $18,%0":"=g" (aSelector):);
413 asm("ldq $19,%0":"=g" (anObject):);
414 asm("bis $31,1,$25");
415 asm("lda $27,objc_msgSend");
416 asm("jsr $26,($27),objc_msgSend");
417 asm("ldgp $29,0($26)");
419 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,anObject);
423 // When the method return a structure, we cannot return it here
424 // becuse we're not called in the right way, so we must return
425 // something else: wether it is self or NULL is a matter of taste.
429 // We fall back here either because the method doesn't return
430 // a structure, or because method is NULL: in this latter
431 // case the call to msgSend will try to forward the message.
432 return objc_msgSend(self, aSelector, anObject);
435 // We fallback here only when aSelector is NULL
436 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
439 - perform:(SEL)aSelector with:obj1 with:obj2
443 _variableStruct *dummyRetVal;
447 method = class_getInstanceMethod((Class)self->isa,
450 method = class_getClassMethod((Class)self->isa,
453 p = &method->method_types[0];
455 // Method returns a structure
456 stack_size = sizeOfReturnedStruct(&p);
457 if(stack_size<MAX_RETSTRUCT_SIZE)
460 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
461 // return structures whose size is not grater than
462 // MAX_RETSTRUCT_SIZE.
463 // This is because the compiler allocates space on the stack
464 // for the size of the return structure, and when the method
465 // returns, the structure is copied on the space allocated
466 // on the stack: if the structure is greater than the space
467 // allocated... bang! (the stack is gone:-)
469 ((callReturnsStruct)objc_msgSend)(self, aSelector, obj1, obj2);
473 dummyRetVal = (_variableStruct*) malloc(stack_size);
475 // Following asm code is equivalent to:
476 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,obj1,obj2);
479 asm("ldq $16,%0":"=g" (dummyRetVal):);
480 asm("ldq $17,%0":"=g" (self):);
481 asm("ldq $18,%0":"=g" (aSelector):);
482 asm("ldq $19,%0":"=g" (obj1):);
483 asm("ldq $20,%0":"=g" (obj2):);
484 asm("bis $31,1,$25");
485 asm("lda $27,objc_msgSend");
486 asm("jsr $26,($27),objc_msgSend");
487 asm("ldgp $29,0($26)");
489 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,obj1,obj2);
493 // When the method return a structure, we cannot return it here
494 // becuse we're not called in the right way, so we must return
495 // something else: wether it is self or NULL is a matter of taste.
499 // We fall back here either because the method doesn't return
500 // a structure, or because method is NULL: in this latter
501 // case the call to msgSend will try to forward the message.
502 return objc_msgSend(self, aSelector, obj1, obj2);
505 // We fallback here only when aSelector is NULL
506 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
510 - perform:(SEL)aSelector
513 return objc_msgSend(self, aSelector);
515 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
518 - perform:(SEL)aSelector with:anObject
521 return objc_msgSend(self, aSelector, anObject);
523 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
526 - perform:(SEL)aSelector with:obj1 with:obj2
529 return objc_msgSend(self, aSelector, obj1, obj2);
531 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
535 - subclassResponsibility:(SEL)aSelector
537 return [self error:_errShouldHaveImp, sel_getName(aSelector)];
540 - notImplemented:(SEL)aSelector
542 return [self error:_errLeftUndone, sel_getName(aSelector)];
545 - doesNotRecognize:(SEL)aMessage
547 return [self error:_errDoesntRecognize,
548 ISMETA (isa) ? '+' : '-', SELNAME(aMessage)];
551 - error:(const char *)aCStr, ...
555 (*_error)(self, aCStr, ap);
556 _objc_error (self, aCStr, ap); /* In case (*_error)() returns. */
561 - (void) printForDebugger:(void *)stream
565 - write:(void *) stream
570 - read:(void *) stream
575 - forward: (SEL) sel : (marg_list) args
577 return [self doesNotRecognize: sel];
580 /* this method is not part of the published API */
582 - (unsigned)methodArgSize:(SEL)sel
584 Method method = class_getInstanceMethod((Class)isa, sel);
585 if (! method) return 0;
586 return method_getSizeOfArguments(method);
589 #if defined(__alpha__)
592 unsigned long int i16;
593 unsigned long int i17;
594 unsigned long int i18;
595 unsigned long int i19;
596 unsigned long int i20;
597 unsigned long int i21;
598 unsigned long int i25;
599 unsigned long int f16;
600 unsigned long int f17;
601 unsigned long int f18;
602 unsigned long int f19;
603 unsigned long int f20;
604 unsigned long int f21;
605 unsigned long int sp;
608 - performv: (SEL) sel : (marg_list) args
613 unsigned long int size;
614 char scratchMem[MAX_RETSTRUCT_SIZE];
617 // Messages to nil object always return nil
618 if (! self) return nil;
620 // Got to have a selector
622 return [self error:_errBadSel, SELNAME(_cmd), sel];
624 // Handle a method which returns a structure and
625 // has been called as such
626 if (((_m_args_p)args)->i25){
627 // Calculate size of the marg_list from the method's
628 // signature. This looks for the method in self
629 // and its superclasses.
630 size = [self methodArgSize: sel];
632 // If neither self nor its superclasses implement
633 // the method, forward the message because self
634 // might know someone who does. This is a
635 // "chained" forward...
636 if (! size) return [self forward: sel: args];
638 // Message self with the specified selector and arguments
639 return objc_msgSendv (self, sel, size, args);
642 // Look for instance method in self's class and superclasses
643 method = class_getInstanceMethod((Class)self->isa,sel);
645 // Look for class method in self's class and superclass
647 method = class_getClassMethod((Class)self->isa,sel);
649 // If neither self nor its superclasses implement
650 // the method, forward the message because self
651 // might know someone who does. This is a
652 // "chained" forward...
654 return [self forward: sel: args];
656 // Calculate size of the marg_list from the method's
658 size = method_getSizeOfArguments(method);
660 // Ready to send message now if the return type
661 // is not a structure
662 p = &method->method_types[0];
664 return objc_msgSendv(self, sel, size, args);
666 // Method returns a structure
667 stack_size = sizeOfReturnedStruct(&p);
668 if(stack_size>=MAX_RETSTRUCT_SIZE)
669 scratchMemP = (char*)malloc(stack_size);
671 scratchMemP = &scratchMem[0];
673 // Set i25 so objc_msgSendv will know that method returns a structure
674 ((_m_args_p)args)->i25 = 1;
676 // Set first param of method to be called to safe return address
677 ((_m_args_p)args)->i16 = (unsigned long int) scratchMemP;
678 objc_msgSendv(self, sel, size, args);
680 if(stack_size>=MAX_RETSTRUCT_SIZE)
686 - performv: (SEL) sel : (marg_list) args
692 // Save ret0 so methods that return a struct might work.
693 asm("copy %%r28, %0": "=r"(ret): );
696 // Messages to nil object always return nil
697 if (! self) return nil;
699 // Calculate size of the marg_list from the method's
700 // signature. This looks for the method in self
701 // and its superclasses.
702 size = [self methodArgSize: sel];
704 // If neither self nor its superclasses implement
705 // it, forward the message because self might know
706 // someone who does. This is a "chained" forward...
707 if (! size) return [self forward: sel: args];
710 // Unfortunately, it looks like the compiler puts something else in
711 // r28 right after this instruction, so this is all for naught.
712 asm("copy %0, %%r28": : "r"(ret));
715 // Message self with the specified selector and arguments
716 return objc_msgSendv (self, sel, size, args);
720 /* Testing protocol conformance */
722 - (BOOL) conformsTo: (Protocol *)aProtocolObj
724 return [(id)isa conformsTo:aProtocolObj];
727 + (BOOL) conformsTo: (Protocol *)aProtocolObj
729 struct objc_class * class;
731 for (class = self; class; class = class->super_class)
733 if (class->isa->version >= 3)
735 struct objc_protocol_list *protocols = class->protocols;
741 for (i = 0; i < protocols->count; i++)
743 Protocol *p = protocols->list[i];
745 if ([p conformsTo:aProtocolObj])
749 if (class->isa->version <= 4)
752 protocols = protocols->next;
760 /* Looking up information for a method */
762 - (struct objc_method_description *) descriptionForMethod:(SEL)aSelector
764 struct objc_class * cls;
765 struct objc_method_description *m;
767 /* Look in the protocols first. */
768 for (cls = isa; cls; cls = cls->super_class)
770 if (cls->isa->version >= 3)
772 struct objc_protocol_list *protocols = cls->protocols;
778 for (i = 0; i < protocols->count; i++)
780 Protocol *p = protocols->list[i];
783 m = [p descriptionForClassMethod:aSelector];
785 m = [p descriptionForInstanceMethod:aSelector];
792 if (cls->isa->version <= 4)
795 protocols = protocols->next;
800 /* Then try the class implementations. */
801 for (cls = isa; cls; cls = cls->super_class) {
804 struct objc_method_list *mlist;
805 while ( (mlist = class_nextMethodList( cls, &iterator )) ) {
806 for (i = 0; i < mlist->method_count; i++)
807 if (mlist->method_list[i].method_name == aSelector) {
808 struct objc_method_description *m;
809 m = (struct objc_method_description *)&mlist->method_list[i];
818 + (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSelector
820 struct objc_class * cls;
822 /* Look in the protocols first. */
823 for (cls = self; cls; cls = cls->super_class)
825 if (cls->isa->version >= 3)
827 struct objc_protocol_list *protocols = cls->protocols;
833 for (i = 0; i < protocols->count; i++)
835 Protocol *p = protocols->list[i];
836 struct objc_method_description *m;
838 if ((m = [p descriptionForInstanceMethod:aSelector]))
842 if (cls->isa->version <= 4)
845 protocols = protocols->next;
850 /* Then try the class implementations. */
851 for (cls = self; cls; cls = cls->super_class) {
854 struct objc_method_list *mlist;
855 while ( (mlist = class_nextMethodList( cls, &iterator )) ) {
856 for (i = 0; i < mlist->method_count; i++)
857 if (mlist->method_list[i].method_name == aSelector) {
858 struct objc_method_description *m;
859 m = (struct objc_method_description *)&mlist->method_list[i];
869 /* Obsolete methods (for binary compatibility only). */
873 return [self superclass];
878 return [self superclass];
881 - (BOOL)isKindOfGivenName:(const char *)aClassName
883 return [self isKindOfClassNamed: aClassName];
886 - (BOOL)isMemberOfGivenName:(const char *)aClassName
888 return [self isMemberOfClassNamed: aClassName];
891 - (struct objc_method_description *) methodDescFor:(SEL)aSelector
893 return [self descriptionForMethod: aSelector];
896 + (struct objc_method_description *) instanceMethodDescFor:(SEL)aSelector
898 return [self descriptionForInstanceMethod: aSelector];
901 - findClass:(const char *)aClassName
903 return (*_cvtToId)(aClassName);
906 - shouldNotImplement:(SEL)aSelector
908 return [self error:_errShouldNotImp, sel_getName(aSelector)];
913 static id _internal_object_copyFromZone(Object *anObject, unsigned nBytes, void *z)
916 register unsigned siz;
921 obj = (*_zoneAlloc)(anObject->isa, nBytes, z);
922 siz = ((struct objc_class *)anObject->isa)->instance_size + nBytes;
923 bcopy((const char*)anObject, (char*)obj, siz);
927 static id _internal_object_copy(Object *anObject, unsigned nBytes)
929 void *z= malloc_zone_from_ptr(anObject);
930 return _internal_object_copyFromZone(anObject,
932 z ? z : malloc_default_zone());
935 static id _internal_object_dispose(Object *anObject)
937 if (anObject==nil) return nil;
938 object_cxxDestruct((id)anObject);
939 anObject->isa = _objc_getFreedObjectClass ();
944 static id _internal_object_reallocFromZone(Object *anObject, unsigned nBytes, void *z)
947 struct objc_class * tmp;
950 __objc_error(nil, _errReAllocNil, 0);
952 if (anObject->isa == _objc_getFreedObjectClass ())
953 __objc_error(anObject, _errReAllocFreed, 0);
955 if (nBytes < ((struct objc_class *)anObject->isa)->instance_size)
956 __objc_error(anObject, _errReAllocTooSmall,
957 object_getClassName(anObject), nBytes);
959 // Make sure not to modify space that has been declared free
961 anObject->isa = _objc_getFreedObjectClass ();
962 newObject = (Object*)malloc_zone_realloc(z, (void*)anObject, (size_t)nBytes);
964 newObject->isa = tmp;
969 __objc_error(anObject, _errNoMem,
970 object_getClassName(anObject), nBytes);
975 static id _internal_object_realloc(Object *anObject, unsigned nBytes)
977 void *z= malloc_zone_from_ptr(anObject);
978 return _internal_object_reallocFromZone(anObject,
980 z ? z : malloc_default_zone());
983 /* Functional Interface to system primitives */
985 id object_copy(Object *anObject, unsigned nBytes)
987 return (*_copy)(anObject, nBytes);
990 id object_copyFromZone(Object *anObject, unsigned nBytes, void *z)
992 return (*_zoneCopy)(anObject, nBytes, z);
995 id object_dispose(Object *anObject)
997 return (*_dealloc)(anObject);
1000 id object_realloc(Object *anObject, unsigned nBytes)
1002 return (*_realloc)(anObject, nBytes);
1005 id object_reallocFromZone(Object *anObject, unsigned nBytes, void *z)
1007 return (*_zoneRealloc)(anObject, nBytes, z);
1010 Ivar object_setInstanceVariable(id obj, const char *name, void *value)
1015 if ((ivar = class_getInstanceVariable(((Object*)obj)->isa, name))) {
1016 objc_assign_ivar((id)value, obj, ivar->ivar_offset);
1022 Ivar object_getInstanceVariable(id obj, const char *name, void **value)
1029 if ((ivar = class_getInstanceVariable(((Object*)obj)->isa, name))) {
1030 ivaridx = (void **)((char *)obj + ivar->ivar_offset);
1039 id (*_copy)(id, unsigned) = _internal_object_copy;
1040 id (*_realloc)(id, unsigned) = _internal_object_realloc;
1041 id (*_dealloc)(id) = _internal_object_dispose;
1042 id (*_cvtToId)(const char *) = objc_lookUpClass;
1043 SEL (*_cvtToSel)(const char *) = sel_getUid;
1044 void (*_error)() = (void(*)())_objc_error;
1045 id (*_zoneCopy)(id, unsigned, void *) = _internal_object_copyFromZone;
1046 id (*_zoneRealloc)(id, unsigned, void *) = _internal_object_reallocFromZone;