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-runtime.h>
33 #import <objc/Protocol.h>
37 OBJC_EXPORT id (*_cvtToId)(const char *);
38 OBJC_EXPORT id (*_poseAs)();
43 _errNoMem[] = "failed -- out of memory(%s, %u)",
44 _errReAllocNil[] = "reallocating nil object",
45 _errReAllocFreed[] = "reallocating freed object",
46 _errReAllocTooSmall[] = "(%s, %u) requested size too small",
47 _errShouldHaveImp[] = "should have implemented the '%s' method.",
48 _errShouldNotImp[] = "should NOT have implemented the '%s' method.",
49 _errLeftUndone[] = "method '%s' not implemented",
50 _errBadSel[] = "method %s given invalid selector %s",
51 _errDoesntRecognize[] = "does not recognize selector %c%s";
54 @implementation Object
69 return (*_poseAs)(self, aFactory);
74 id newObject = (*_alloc)((Class)self, 0);
75 struct objc_class * metaClass = ((struct objc_class *) self)->isa;
76 if (metaClass->version > 1)
77 return [newObject init];
84 return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
87 + allocFromZone:(void *) z
89 return (*_zoneAlloc)((Class)self, 0, z);
99 return ((struct objc_class *)isa)->name;
104 return ((struct objc_class *)self)->name;
109 return ((uarith_t)self) >> 2;
112 - (BOOL)isEqual:anObject
114 return anObject == self;
119 return (*_dealloc)(self);
144 void *z = malloc_zone_from_ptr(self);
145 return z ? z : malloc_default_zone();
150 return ((struct objc_class *)self)->super_class;
155 return ((struct objc_class *)isa)->super_class;
160 struct objc_class * class = (struct objc_class *) self;
161 return class->version;
164 + setVersion: (int) aVersion
166 struct objc_class * class = (struct objc_class *) self;
167 class->version = aVersion;
171 - (BOOL)isKindOf:aClass
174 for (cls = isa; cls; cls = ((struct objc_class *)cls)->super_class)
175 if (cls == (Class)aClass)
180 - (BOOL)isMemberOf:aClass
182 return isa == (Class)aClass;
185 - (BOOL)isKindOfClassNamed:(const char *)aClassName
188 for (cls = isa; cls; cls = ((struct objc_class *)cls)->super_class)
189 if (strcmp(aClassName, ((struct objc_class *)cls)->name) == 0)
194 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
196 return strcmp(aClassName, ((struct objc_class *)isa)->name) == 0;
199 + (BOOL)instancesRespondTo:(SEL)aSelector
201 return class_respondsToMethod((Class)self, aSelector);
204 - (BOOL)respondsTo:(SEL)aSelector
206 return class_respondsToMethod(isa, aSelector);
211 return [self copyFromZone: [self zone]];
214 - copyFromZone:(void *)z
216 return (*_zoneCopy)(self, 0, z);
219 - (IMP)methodFor:(SEL)aSelector
221 return class_lookupMethod(isa, aSelector);
224 + (IMP)instanceMethodFor:(SEL)aSelector
226 return class_lookupMethod(self, aSelector);
229 #if defined(__alpha__)
230 #define MAX_RETSTRUCT_SIZE 256
232 typedef struct _foolGCC {
233 char c[MAX_RETSTRUCT_SIZE];
236 typedef _variableStruct (*callReturnsStruct)();
238 OBJC_EXPORT long sizeOfReturnedStruct(char **);
240 long sizeOfType(char **pp)
243 long stack_size = 0, n = 0;
247 stack_size += sizeof(char); // Alignment ?
251 stack_size += sizeof(short);// Alignment ?
256 stack_size += sizeof(int);
260 stack_size += sizeof(long int);
263 stack_size += sizeof(float);
266 stack_size += sizeof(double);
272 stack_size += sizeof(char*);
275 stack_size += sizeOfReturnedStruct(&p);
281 n = 10 * n + (*p++ - '0');
282 stack_size += (n * sizeOfType(&p));
292 sizeOfReturnedStruct(char **pp)
295 long stack_size = 0, n = 0;
296 while(p!=NULL && *++p!='=') ; // skip the struct name
297 while(p!=NULL && *++p!='}')
298 stack_size += sizeOfType(&p);
299 return stack_size + 8; // Add 8 as a 'forfait value'
300 // to take alignment into account
303 - perform:(SEL)aSelector
307 _variableStruct *dummyRetVal;
311 method = class_getInstanceMethod((Class)self->isa,
314 method = class_getClassMethod((Class)self->isa,
317 p = &method->method_types[0];
319 // Method returns a structure
320 stack_size = sizeOfReturnedStruct(&p);
321 if(stack_size<MAX_RETSTRUCT_SIZE)
324 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
325 // return structures whose size is not grater than
326 // MAX_RETSTRUCT_SIZE.
327 // This is because the compiler allocates space on the stack
328 // for the size of the return structure, and when the method
329 // returns, the structure is copied on the space allocated
330 // on the stack: if the structure is greater than the space
331 // allocated... bang! (the stack is gone:-)
333 ((callReturnsStruct)objc_msgSend)(self, aSelector);
337 dummyRetVal = (_variableStruct*) malloc(stack_size);
339 // Following asm code is equivalent to:
340 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector);
342 asm("ldq $16,%0":"=g" (dummyRetVal):);
343 asm("ldq $17,%0":"=g" (self):);
344 asm("ldq $18,%0":"=g" (aSelector):);
345 asm("bis $31,1,$25");
346 asm("lda $27,objc_msgSend");
347 asm("jsr $26,($27),objc_msgSend");
348 asm("ldgp $29,0($26)");
350 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector);
354 // When the method return a structure, we cannot return it here
355 // becuse we're not called in the right way, so we must return
356 // something else: wether it is self or NULL is a matter of taste.
360 // We fall back here either because the method doesn't return
361 // a structure, or because method is NULL: in this latter
362 // case the call to msgSend will try to forward the message.
363 return objc_msgSend(self, aSelector);
366 // We fallback here only when aSelector is NULL
367 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
370 - perform:(SEL)aSelector with:anObject
374 _variableStruct *dummyRetVal;
378 method = class_getInstanceMethod((Class)self->isa,
381 method = class_getClassMethod((Class)self->isa,
384 p = &method->method_types[0];
386 // Method returns a structure
387 stack_size = sizeOfReturnedStruct(&p);
388 if(stack_size<MAX_RETSTRUCT_SIZE)
391 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
392 // return structures whose size is not grater than
393 // MAX_RETSTRUCT_SIZE.
394 // This is because the compiler allocates space on the stack
395 // for the size of the return structure, and when the method
396 // returns, the structure is copied on the space allocated
397 // on the stack: if the structure is greater than the space
398 // allocated... bang! (the stack is gone:-)
400 ((callReturnsStruct)objc_msgSend)(self, aSelector, anObject);
404 dummyRetVal = (_variableStruct*) malloc(stack_size);
406 // Following asm code is equivalent to:
407 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,anObject);
409 asm("ldq $16,%0":"=g" (dummyRetVal):);
410 asm("ldq $17,%0":"=g" (self):);
411 asm("ldq $18,%0":"=g" (aSelector):);
412 asm("ldq $19,%0":"=g" (anObject):);
413 asm("bis $31,1,$25");
414 asm("lda $27,objc_msgSend");
415 asm("jsr $26,($27),objc_msgSend");
416 asm("ldgp $29,0($26)");
418 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,anObject);
422 // When the method return a structure, we cannot return it here
423 // becuse we're not called in the right way, so we must return
424 // something else: wether it is self or NULL is a matter of taste.
428 // We fall back here either because the method doesn't return
429 // a structure, or because method is NULL: in this latter
430 // case the call to msgSend will try to forward the message.
431 return objc_msgSend(self, aSelector, anObject);
434 // We fallback here only when aSelector is NULL
435 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
438 - perform:(SEL)aSelector with:obj1 with:obj2
442 _variableStruct *dummyRetVal;
446 method = class_getInstanceMethod((Class)self->isa,
449 method = class_getClassMethod((Class)self->isa,
452 p = &method->method_types[0];
454 // Method returns a structure
455 stack_size = sizeOfReturnedStruct(&p);
456 if(stack_size<MAX_RETSTRUCT_SIZE)
459 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
460 // return structures whose size is not grater than
461 // MAX_RETSTRUCT_SIZE.
462 // This is because the compiler allocates space on the stack
463 // for the size of the return structure, and when the method
464 // returns, the structure is copied on the space allocated
465 // on the stack: if the structure is greater than the space
466 // allocated... bang! (the stack is gone:-)
468 ((callReturnsStruct)objc_msgSend)(self, aSelector, obj1, obj2);
472 dummyRetVal = (_variableStruct*) malloc(stack_size);
474 // Following asm code is equivalent to:
475 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,obj1,obj2);
478 asm("ldq $16,%0":"=g" (dummyRetVal):);
479 asm("ldq $17,%0":"=g" (self):);
480 asm("ldq $18,%0":"=g" (aSelector):);
481 asm("ldq $19,%0":"=g" (obj1):);
482 asm("ldq $20,%0":"=g" (obj2):);
483 asm("bis $31,1,$25");
484 asm("lda $27,objc_msgSend");
485 asm("jsr $26,($27),objc_msgSend");
486 asm("ldgp $29,0($26)");
488 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,obj1,obj2);
492 // When the method return a structure, we cannot return it here
493 // becuse we're not called in the right way, so we must return
494 // something else: wether it is self or NULL is a matter of taste.
498 // We fall back here either because the method doesn't return
499 // a structure, or because method is NULL: in this latter
500 // case the call to msgSend will try to forward the message.
501 return objc_msgSend(self, aSelector, obj1, obj2);
504 // We fallback here only when aSelector is NULL
505 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
509 - perform:(SEL)aSelector
512 return objc_msgSend(self, aSelector);
514 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
517 - perform:(SEL)aSelector with:anObject
520 return objc_msgSend(self, aSelector, anObject);
522 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
525 - perform:(SEL)aSelector with:obj1 with:obj2
528 return objc_msgSend(self, aSelector, obj1, obj2);
530 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
534 - subclassResponsibility:(SEL)aSelector
536 return [self error:_errShouldHaveImp, sel_getName(aSelector)];
539 - notImplemented:(SEL)aSelector
541 return [self error:_errLeftUndone, sel_getName(aSelector)];
544 - doesNotRecognize:(SEL)aMessage
546 return [self error:_errDoesntRecognize,
547 ISMETA (isa) ? '+' : '-', SELNAME(aMessage)];
550 - error:(const char *)aCStr, ...
554 (*_error)(self, aCStr, ap);
555 _objc_error (self, aCStr, ap); /* In case (*_error)() returns. */
560 - (void) printForDebugger:(void *)stream
564 - write:(void *) stream
569 - read:(void *) stream
574 - forward: (SEL) sel : (marg_list) args
576 return [self doesNotRecognize: sel];
579 /* this method is not part of the published API */
581 - (unsigned)methodArgSize:(SEL)sel
583 Method method = class_getInstanceMethod((Class)isa, sel);
584 if (! method) return 0;
585 return method_getSizeOfArguments(method);
588 #if defined(__alpha__)
591 unsigned long int i16;
592 unsigned long int i17;
593 unsigned long int i18;
594 unsigned long int i19;
595 unsigned long int i20;
596 unsigned long int i21;
597 unsigned long int i25;
598 unsigned long int f16;
599 unsigned long int f17;
600 unsigned long int f18;
601 unsigned long int f19;
602 unsigned long int f20;
603 unsigned long int f21;
604 unsigned long int sp;
607 - performv: (SEL) sel : (marg_list) args
612 unsigned long int size;
613 char scratchMem[MAX_RETSTRUCT_SIZE];
616 // Messages to nil object always return nil
617 if (! self) return nil;
619 // Got to have a selector
621 return [self error:_errBadSel, SELNAME(_cmd), sel];
623 // Handle a method which returns a structure and
624 // has been called as such
625 if (((_m_args_p)args)->i25){
626 // Calculate size of the marg_list from the method's
627 // signature. This looks for the method in self
628 // and its superclasses.
629 size = [self methodArgSize: sel];
631 // If neither self nor its superclasses implement
632 // the method, forward the message because self
633 // might know someone who does. This is a
634 // "chained" forward...
635 if (! size) return [self forward: sel: args];
637 // Message self with the specified selector and arguments
638 return objc_msgSendv (self, sel, size, args);
641 // Look for instance method in self's class and superclasses
642 method = class_getInstanceMethod((Class)self->isa,sel);
644 // Look for class method in self's class and superclass
646 method = class_getClassMethod((Class)self->isa,sel);
648 // If neither self nor its superclasses implement
649 // the method, forward the message because self
650 // might know someone who does. This is a
651 // "chained" forward...
653 return [self forward: sel: args];
655 // Calculate size of the marg_list from the method's
657 size = method_getSizeOfArguments(method);
659 // Ready to send message now if the return type
660 // is not a structure
661 p = &method->method_types[0];
663 return objc_msgSendv(self, sel, size, args);
665 // Method returns a structure
666 stack_size = sizeOfReturnedStruct(&p);
667 if(stack_size>=MAX_RETSTRUCT_SIZE)
668 scratchMemP = (char*)malloc(stack_size);
670 scratchMemP = &scratchMem[0];
672 // Set i25 so objc_msgSendv will know that method returns a structure
673 ((_m_args_p)args)->i25 = 1;
675 // Set first param of method to be called to safe return address
676 ((_m_args_p)args)->i16 = (unsigned long int) scratchMemP;
677 objc_msgSendv(self, sel, size, args);
679 if(stack_size>=MAX_RETSTRUCT_SIZE)
685 - performv: (SEL) sel : (marg_list) args
691 // Save ret0 so methods that return a struct might work.
692 asm("copy %%r28, %0": "=r"(ret): );
695 // Messages to nil object always return nil
696 if (! self) return nil;
698 // Calculate size of the marg_list from the method's
699 // signature. This looks for the method in self
700 // and its superclasses.
701 size = [self methodArgSize: sel];
703 // If neither self nor its superclasses implement
704 // it, forward the message because self might know
705 // someone who does. This is a "chained" forward...
706 if (! size) return [self forward: sel: args];
709 // Unfortunately, it looks like the compiler puts something else in
710 // r28 right after this instruction, so this is all for naught.
711 asm("copy %0, %%r28": : "r"(ret));
714 // Message self with the specified selector and arguments
715 return objc_msgSendv (self, sel, size, args);
719 /* Testing protocol conformance */
721 - (BOOL) conformsTo: (Protocol *)aProtocolObj
723 return [(id)isa conformsTo:aProtocolObj];
726 + (BOOL) conformsTo: (Protocol *)aProtocolObj
728 struct objc_class * class;
730 for (class = self; class; class = class->super_class)
732 if (class->isa->version >= 3)
734 struct objc_protocol_list *protocols = class->protocols;
740 for (i = 0; i < protocols->count; i++)
742 Protocol *p = protocols->list[i];
744 if ([p conformsTo:aProtocolObj])
748 if (class->isa->version <= 4)
751 protocols = protocols->next;
759 /* Looking up information for a method */
761 - (struct objc_method_description *) descriptionForMethod:(SEL)aSelector
763 struct objc_class * cls;
764 struct objc_method_description *m;
766 /* Look in the protocols first. */
767 for (cls = isa; cls; cls = cls->super_class)
769 if (cls->isa->version >= 3)
771 struct objc_protocol_list *protocols = cls->protocols;
777 for (i = 0; i < protocols->count; i++)
779 Protocol *p = protocols->list[i];
782 m = [p descriptionForClassMethod:aSelector];
784 m = [p descriptionForInstanceMethod:aSelector];
791 if (cls->isa->version <= 4)
794 protocols = protocols->next;
799 /* Then try the class implementations. */
800 for (cls = isa; cls; cls = cls->super_class) {
803 struct objc_method_list *mlist;
804 while ( (mlist = _class_inlinedNextMethodList( cls, &iterator )) ) {
805 for (i = 0; i < mlist->method_count; i++)
806 if (mlist->method_list[i].method_name == aSelector) {
807 struct objc_method_description *m;
808 m = (struct objc_method_description *)&mlist->method_list[i];
817 + (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSelector
819 struct objc_class * cls;
821 /* Look in the protocols first. */
822 for (cls = self; cls; cls = cls->super_class)
824 if (cls->isa->version >= 3)
826 struct objc_protocol_list *protocols = cls->protocols;
832 for (i = 0; i < protocols->count; i++)
834 Protocol *p = protocols->list[i];
835 struct objc_method_description *m;
837 if ((m = [p descriptionForInstanceMethod:aSelector]))
841 if (cls->isa->version <= 4)
844 protocols = protocols->next;
849 /* Then try the class implementations. */
850 for (cls = self; cls; cls = cls->super_class) {
853 struct objc_method_list *mlist;
854 while ( (mlist = _class_inlinedNextMethodList( cls, &iterator )) ) {
855 for (i = 0; i < mlist->method_count; i++)
856 if (mlist->method_list[i].method_name == aSelector) {
857 struct objc_method_description *m;
858 m = (struct objc_method_description *)&mlist->method_list[i];
868 /* Obsolete methods (for binary compatibility only). */
872 return [self superclass];
877 return [self superclass];
880 - (BOOL)isKindOfGivenName:(const char *)aClassName
882 return [self isKindOfClassNamed: aClassName];
885 - (BOOL)isMemberOfGivenName:(const char *)aClassName
887 return [self isMemberOfClassNamed: aClassName];
890 - (struct objc_method_description *) methodDescFor:(SEL)aSelector
892 return [self descriptionForMethod: aSelector];
895 + (struct objc_method_description *) instanceMethodDescFor:(SEL)aSelector
897 return [self descriptionForInstanceMethod: aSelector];
900 - findClass:(const char *)aClassName
902 return (*_cvtToId)(aClassName);
905 - shouldNotImplement:(SEL)aSelector
907 return [self error:_errShouldNotImp, sel_getName(aSelector)];
912 static id _internal_object_copyFromZone(Object *anObject, unsigned nBytes, void *z)
915 register unsigned siz;
920 obj = (*_zoneAlloc)(anObject->isa, nBytes, z);
921 siz = ((struct objc_class *)anObject->isa)->instance_size + nBytes;
922 bcopy((const char*)anObject, (char*)obj, siz);
926 static id _internal_object_copy(Object *anObject, unsigned nBytes)
928 void *z= malloc_zone_from_ptr(anObject);
929 return _internal_object_copyFromZone(anObject,
931 z ? z : malloc_default_zone());
934 static id _internal_object_dispose(Object *anObject)
936 if (anObject==nil) return nil;
937 anObject->isa = _objc_getFreedObjectClass ();
942 static id _internal_object_reallocFromZone(Object *anObject, unsigned nBytes, void *z)
945 struct objc_class * tmp;
948 __objc_error(nil, _errReAllocNil, 0);
950 if (anObject->isa == _objc_getFreedObjectClass ())
951 __objc_error(anObject, _errReAllocFreed, 0);
953 if (nBytes < ((struct objc_class *)anObject->isa)->instance_size)
954 __objc_error(anObject, _errReAllocTooSmall,
955 object_getClassName(anObject), nBytes);
957 // Make sure not to modify space that has been declared free
959 anObject->isa = _objc_getFreedObjectClass ();
960 newObject = (Object*)malloc_zone_realloc(z, (void*)anObject, (size_t)nBytes);
962 newObject->isa = tmp;
967 __objc_error(anObject, _errNoMem,
968 object_getClassName(anObject), nBytes);
973 static id _internal_object_realloc(Object *anObject, unsigned nBytes)
975 void *z= malloc_zone_from_ptr(anObject);
976 return _internal_object_reallocFromZone(anObject,
978 z ? z : malloc_default_zone());
981 /* Functional Interface to system primitives */
983 id object_copy(Object *anObject, unsigned nBytes)
985 return (*_copy)(anObject, nBytes);
988 id object_copyFromZone(Object *anObject, unsigned nBytes, void *z)
990 return (*_zoneCopy)(anObject, nBytes, z);
993 id object_dispose(Object *anObject)
995 return (*_dealloc)(anObject);
998 id object_realloc(Object *anObject, unsigned nBytes)
1000 return (*_realloc)(anObject, nBytes);
1003 id object_reallocFromZone(Object *anObject, unsigned nBytes, void *z)
1005 return (*_zoneRealloc)(anObject, nBytes, z);
1008 Ivar object_setInstanceVariable(id obj, const char *name, void *value)
1015 if ((ivar = class_getInstanceVariable(((Object*)obj)->isa, name))) {
1016 ivaridx = (void **)((char *)obj + ivar->ivar_offset);
1023 Ivar object_getInstanceVariable(id obj, const char *name, void **value)
1030 if ((ivar = class_getInstanceVariable(((Object*)obj)->isa, name))) {
1031 ivaridx = (void **)((char *)obj + ivar->ivar_offset);
1040 id (*_copy)(id, unsigned) = _internal_object_copy;
1041 id (*_realloc)(id, unsigned) = _internal_object_realloc;
1042 id (*_dealloc)(id) = _internal_object_dispose;
1043 id (*_cvtToId)(const char *) = objc_lookUpClass;
1044 SEL (*_cvtToSel)(const char *) = sel_getUid;
1045 void (*_error)() = (void(*)())_objc_error;
1046 id (*_zoneCopy)(id, unsigned, void *) = _internal_object_copyFromZone;
1047 id (*_zoneRealloc)(id, unsigned, void *) = _internal_object_reallocFromZone;