2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
26 Copyright 1988-1996 NeXT Software, Inc.
29 #import <objc/Object.h>
30 #import "objc-private.h"
31 #import <objc/objc-runtime.h>
32 #import <objc/Protocol.h>
36 OBJC_EXPORT id (*_cvtToId)(const char *);
37 OBJC_EXPORT id (*_poseAs)();
42 _errNoMem[] = "failed -- out of memory(%s, %u)",
43 _errReAllocNil[] = "reallocating nil object",
44 _errReAllocFreed[] = "reallocating freed object",
45 _errReAllocTooSmall[] = "(%s, %u) requested size too small",
46 _errShouldHaveImp[] = "should have implemented the '%s' method.",
47 _errShouldNotImp[] = "should NOT have implemented the '%s' method.",
48 _errLeftUndone[] = "method '%s' not implemented",
49 _errBadSel[] = "method %s given invalid selector %s",
50 _errDoesntRecognize[] = "does not recognize selector %c%s";
53 @implementation Object
68 return (*_poseAs)(self, aFactory);
73 id newObject = (*_alloc)((Class)self, 0);
74 struct objc_class * metaClass = ((struct objc_class *) self)->isa;
75 if (metaClass->version > 1)
76 return [newObject init];
83 return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
86 + allocFromZone:(void *) z
88 return (*_zoneAlloc)((Class)self, 0, z);
98 return ((struct objc_class *)isa)->name;
103 return ((struct objc_class *)self)->name;
108 return ((uarith_t)self) >> 2;
111 - (BOOL)isEqual:anObject
113 return anObject == self;
118 return (*_dealloc)(self);
143 void *z = malloc_zone_from_ptr(self);
144 return z ? z : malloc_default_zone();
149 return ((struct objc_class *)self)->super_class;
154 return ((struct objc_class *)isa)->super_class;
159 struct objc_class * class = (struct objc_class *) self;
160 return class->version;
163 + setVersion: (int) aVersion
165 struct objc_class * class = (struct objc_class *) self;
166 class->version = aVersion;
170 - (BOOL)isKindOf:aClass
173 for (cls = isa; cls; cls = ((struct objc_class *)cls)->super_class)
174 if (cls == (Class)aClass)
179 - (BOOL)isMemberOf:aClass
181 return isa == (Class)aClass;
184 - (BOOL)isKindOfClassNamed:(const char *)aClassName
187 for (cls = isa; cls; cls = ((struct objc_class *)cls)->super_class)
188 if (strcmp(aClassName, ((struct objc_class *)cls)->name) == 0)
193 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
195 return strcmp(aClassName, ((struct objc_class *)isa)->name) == 0;
198 + (BOOL)instancesRespondTo:(SEL)aSelector
200 return class_respondsToMethod((Class)self, aSelector);
203 - (BOOL)respondsTo:(SEL)aSelector
205 return class_respondsToMethod(isa, aSelector);
210 return [self copyFromZone: [self zone]];
213 - copyFromZone:(void *)z
215 return (*_zoneCopy)(self, 0, z);
218 - (IMP)methodFor:(SEL)aSelector
220 return class_lookupMethod(isa, aSelector);
223 + (IMP)instanceMethodFor:(SEL)aSelector
225 return class_lookupMethod(self, aSelector);
228 #if defined(__alpha__)
229 #define MAX_RETSTRUCT_SIZE 256
231 typedef struct _foolGCC {
232 char c[MAX_RETSTRUCT_SIZE];
235 typedef _variableStruct (*callReturnsStruct)();
237 OBJC_EXPORT long sizeOfReturnedStruct(char **);
239 long sizeOfType(char **pp)
242 long stack_size = 0, n = 0;
246 stack_size += sizeof(char); // Alignment ?
250 stack_size += sizeof(short);// Alignment ?
255 stack_size += sizeof(int);
259 stack_size += sizeof(long int);
262 stack_size += sizeof(float);
265 stack_size += sizeof(double);
271 stack_size += sizeof(char*);
274 stack_size += sizeOfReturnedStruct(&p);
280 n = 10 * n + (*p++ - '0');
281 stack_size += (n * sizeOfType(&p));
291 sizeOfReturnedStruct(char **pp)
294 long stack_size = 0, n = 0;
295 while(p!=NULL && *++p!='=') ; // skip the struct name
296 while(p!=NULL && *++p!='}')
297 stack_size += sizeOfType(&p);
298 return stack_size + 8; // Add 8 as a 'forfait value'
299 // to take alignment into account
302 - perform:(SEL)aSelector
306 _variableStruct *dummyRetVal;
310 method = class_getInstanceMethod((Class)self->isa,
313 method = class_getClassMethod((Class)self->isa,
316 p = &method->method_types[0];
318 // Method returns a structure
319 stack_size = sizeOfReturnedStruct(&p);
320 if(stack_size<MAX_RETSTRUCT_SIZE)
323 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
324 // return structures whose size is not grater than
325 // MAX_RETSTRUCT_SIZE.
326 // This is because the compiler allocates space on the stack
327 // for the size of the return structure, and when the method
328 // returns, the structure is copied on the space allocated
329 // on the stack: if the structure is greater than the space
330 // allocated... bang! (the stack is gone:-)
332 ((callReturnsStruct)objc_msgSend)(self, aSelector);
336 dummyRetVal = (_variableStruct*) malloc(stack_size);
338 // Following asm code is equivalent to:
339 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector);
341 asm("ldq $16,%0":"=g" (dummyRetVal):);
342 asm("ldq $17,%0":"=g" (self):);
343 asm("ldq $18,%0":"=g" (aSelector):);
344 asm("bis $31,1,$25");
345 asm("lda $27,objc_msgSend");
346 asm("jsr $26,($27),objc_msgSend");
347 asm("ldgp $29,0($26)");
349 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector);
353 // When the method return a structure, we cannot return it here
354 // becuse we're not called in the right way, so we must return
355 // something else: wether it is self or NULL is a matter of taste.
359 // We fall back here either because the method doesn't return
360 // a structure, or because method is NULL: in this latter
361 // case the call to msgSend will try to forward the message.
362 return objc_msgSend(self, aSelector);
365 // We fallback here only when aSelector is NULL
366 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
369 - perform:(SEL)aSelector with:anObject
373 _variableStruct *dummyRetVal;
377 method = class_getInstanceMethod((Class)self->isa,
380 method = class_getClassMethod((Class)self->isa,
383 p = &method->method_types[0];
385 // Method returns a structure
386 stack_size = sizeOfReturnedStruct(&p);
387 if(stack_size<MAX_RETSTRUCT_SIZE)
390 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
391 // return structures whose size is not grater than
392 // MAX_RETSTRUCT_SIZE.
393 // This is because the compiler allocates space on the stack
394 // for the size of the return structure, and when the method
395 // returns, the structure is copied on the space allocated
396 // on the stack: if the structure is greater than the space
397 // allocated... bang! (the stack is gone:-)
399 ((callReturnsStruct)objc_msgSend)(self, aSelector, anObject);
403 dummyRetVal = (_variableStruct*) malloc(stack_size);
405 // Following asm code is equivalent to:
406 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,anObject);
408 asm("ldq $16,%0":"=g" (dummyRetVal):);
409 asm("ldq $17,%0":"=g" (self):);
410 asm("ldq $18,%0":"=g" (aSelector):);
411 asm("ldq $19,%0":"=g" (anObject):);
412 asm("bis $31,1,$25");
413 asm("lda $27,objc_msgSend");
414 asm("jsr $26,($27),objc_msgSend");
415 asm("ldgp $29,0($26)");
417 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,anObject);
421 // When the method return a structure, we cannot return it here
422 // becuse we're not called in the right way, so we must return
423 // something else: wether it is self or NULL is a matter of taste.
427 // We fall back here either because the method doesn't return
428 // a structure, or because method is NULL: in this latter
429 // case the call to msgSend will try to forward the message.
430 return objc_msgSend(self, aSelector, anObject);
433 // We fallback here only when aSelector is NULL
434 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
437 - perform:(SEL)aSelector with:obj1 with:obj2
441 _variableStruct *dummyRetVal;
445 method = class_getInstanceMethod((Class)self->isa,
448 method = class_getClassMethod((Class)self->isa,
451 p = &method->method_types[0];
453 // Method returns a structure
454 stack_size = sizeOfReturnedStruct(&p);
455 if(stack_size<MAX_RETSTRUCT_SIZE)
458 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
459 // return structures whose size is not grater than
460 // MAX_RETSTRUCT_SIZE.
461 // This is because the compiler allocates space on the stack
462 // for the size of the return structure, and when the method
463 // returns, the structure is copied on the space allocated
464 // on the stack: if the structure is greater than the space
465 // allocated... bang! (the stack is gone:-)
467 ((callReturnsStruct)objc_msgSend)(self, aSelector, obj1, obj2);
471 dummyRetVal = (_variableStruct*) malloc(stack_size);
473 // Following asm code is equivalent to:
474 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,obj1,obj2);
477 asm("ldq $16,%0":"=g" (dummyRetVal):);
478 asm("ldq $17,%0":"=g" (self):);
479 asm("ldq $18,%0":"=g" (aSelector):);
480 asm("ldq $19,%0":"=g" (obj1):);
481 asm("ldq $20,%0":"=g" (obj2):);
482 asm("bis $31,1,$25");
483 asm("lda $27,objc_msgSend");
484 asm("jsr $26,($27),objc_msgSend");
485 asm("ldgp $29,0($26)");
487 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,obj1,obj2);
491 // When the method return a structure, we cannot return it here
492 // becuse we're not called in the right way, so we must return
493 // something else: wether it is self or NULL is a matter of taste.
497 // We fall back here either because the method doesn't return
498 // a structure, or because method is NULL: in this latter
499 // case the call to msgSend will try to forward the message.
500 return objc_msgSend(self, aSelector, obj1, obj2);
503 // We fallback here only when aSelector is NULL
504 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
508 - perform:(SEL)aSelector
511 return objc_msgSend(self, aSelector);
513 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
516 - perform:(SEL)aSelector with:anObject
519 return objc_msgSend(self, aSelector, anObject);
521 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
524 - perform:(SEL)aSelector with:obj1 with:obj2
527 return objc_msgSend(self, aSelector, obj1, obj2);
529 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
533 - subclassResponsibility:(SEL)aSelector
535 return [self error:_errShouldHaveImp, sel_getName(aSelector)];
538 - notImplemented:(SEL)aSelector
540 return [self error:_errLeftUndone, sel_getName(aSelector)];
543 - doesNotRecognize:(SEL)aMessage
545 return [self error:_errDoesntRecognize,
546 ISMETA (isa) ? '+' : '-', SELNAME(aMessage)];
549 - error:(const char *)aCStr, ...
553 (*_error)(self, aCStr, ap);
554 _objc_error (self, aCStr, ap); /* In case (*_error)() returns. */
559 - (void) printForDebugger:(void *)stream
563 - write:(void *) stream
568 - read:(void *) stream
573 - forward: (SEL) sel : (marg_list) args
575 return [self doesNotRecognize: sel];
578 /* this method is not part of the published API */
580 - (unsigned)methodArgSize:(SEL)sel
582 Method method = class_getInstanceMethod((Class)isa, sel);
583 if (! method) return 0;
584 return method_getSizeOfArguments(method);
587 #if defined(__alpha__)
590 unsigned long int i16;
591 unsigned long int i17;
592 unsigned long int i18;
593 unsigned long int i19;
594 unsigned long int i20;
595 unsigned long int i21;
596 unsigned long int i25;
597 unsigned long int f16;
598 unsigned long int f17;
599 unsigned long int f18;
600 unsigned long int f19;
601 unsigned long int f20;
602 unsigned long int f21;
603 unsigned long int sp;
606 - performv: (SEL) sel : (marg_list) args
611 unsigned long int size;
612 char scratchMem[MAX_RETSTRUCT_SIZE];
615 // Messages to nil object always return nil
616 if (! self) return nil;
618 // Got to have a selector
620 return [self error:_errBadSel, SELNAME(_cmd), sel];
622 // Handle a method which returns a structure and
623 // has been called as such
624 if (((_m_args_p)args)->i25){
625 // Calculate size of the marg_list from the method's
626 // signature. This looks for the method in self
627 // and its superclasses.
628 size = [self methodArgSize: sel];
630 // If neither self nor its superclasses implement
631 // the method, forward the message because self
632 // might know someone who does. This is a
633 // "chained" forward...
634 if (! size) return [self forward: sel: args];
636 // Message self with the specified selector and arguments
637 return objc_msgSendv (self, sel, size, args);
640 // Look for instance method in self's class and superclasses
641 method = class_getInstanceMethod((Class)self->isa,sel);
643 // Look for class method in self's class and superclass
645 method = class_getClassMethod((Class)self->isa,sel);
647 // If neither self nor its superclasses implement
648 // the method, forward the message because self
649 // might know someone who does. This is a
650 // "chained" forward...
652 return [self forward: sel: args];
654 // Calculate size of the marg_list from the method's
656 size = method_getSizeOfArguments(method);
658 // Ready to send message now if the return type
659 // is not a structure
660 p = &method->method_types[0];
662 return objc_msgSendv(self, sel, size, args);
664 // Method returns a structure
665 stack_size = sizeOfReturnedStruct(&p);
666 if(stack_size>=MAX_RETSTRUCT_SIZE)
667 scratchMemP = (char*)malloc(stack_size);
669 scratchMemP = &scratchMem[0];
671 // Set i25 so objc_msgSendv will know that method returns a structure
672 ((_m_args_p)args)->i25 = 1;
674 // Set first param of method to be called to safe return address
675 ((_m_args_p)args)->i16 = (unsigned long int) scratchMemP;
676 objc_msgSendv(self, sel, size, args);
678 if(stack_size>=MAX_RETSTRUCT_SIZE)
684 - performv: (SEL) sel : (marg_list) args
690 // Save ret0 so methods that return a struct might work.
691 asm("copy %%r28, %0": "=r"(ret): );
694 // Messages to nil object always return nil
695 if (! self) return nil;
697 // Calculate size of the marg_list from the method's
698 // signature. This looks for the method in self
699 // and its superclasses.
700 size = [self methodArgSize: sel];
702 // If neither self nor its superclasses implement
703 // it, forward the message because self might know
704 // someone who does. This is a "chained" forward...
705 if (! size) return [self forward: sel: args];
708 // Unfortunately, it looks like the compiler puts something else in
709 // r28 right after this instruction, so this is all for naught.
710 asm("copy %0, %%r28": : "r"(ret));
713 // Message self with the specified selector and arguments
714 return objc_msgSendv (self, sel, size, args);
718 /* Testing protocol conformance */
720 - (BOOL) conformsTo: (Protocol *)aProtocolObj
722 return [(id)isa conformsTo:aProtocolObj];
725 + (BOOL) conformsTo: (Protocol *)aProtocolObj
727 struct objc_class * class;
729 for (class = self; class; class = class->super_class)
731 if (class->isa->version >= 3)
733 struct objc_protocol_list *protocols = class->protocols;
739 for (i = 0; i < protocols->count; i++)
741 Protocol *p = protocols->list[i];
743 if ([p conformsTo:aProtocolObj])
747 if (class->isa->version <= 4)
750 protocols = protocols->next;
758 /* Looking up information for a method */
760 - (struct objc_method_description *) descriptionForMethod:(SEL)aSelector
762 struct objc_class * cls;
763 struct objc_method_description *m;
765 /* Look in the protocols first. */
766 for (cls = isa; cls; cls = cls->super_class)
768 if (cls->isa->version >= 3)
770 struct objc_protocol_list *protocols = cls->protocols;
776 for (i = 0; i < protocols->count; i++)
778 Protocol *p = protocols->list[i];
781 m = [p descriptionForClassMethod:aSelector];
783 m = [p descriptionForInstanceMethod:aSelector];
790 if (cls->isa->version <= 4)
793 protocols = protocols->next;
798 /* Then try the class implementations. */
799 for (cls = isa; cls; cls = cls->super_class) {
802 struct objc_method_list *mlist;
803 while ( (mlist = _class_inlinedNextMethodList( cls, &iterator )) ) {
804 for (i = 0; i < mlist->method_count; i++)
805 if (mlist->method_list[i].method_name == aSelector) {
806 struct objc_method_description *m;
807 m = (struct objc_method_description *)&mlist->method_list[i];
816 + (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSelector
818 struct objc_class * cls;
820 /* Look in the protocols first. */
821 for (cls = self; cls; cls = cls->super_class)
823 if (cls->isa->version >= 3)
825 struct objc_protocol_list *protocols = cls->protocols;
831 for (i = 0; i < protocols->count; i++)
833 Protocol *p = protocols->list[i];
834 struct objc_method_description *m;
836 if ((m = [p descriptionForInstanceMethod:aSelector]))
840 if (cls->isa->version <= 4)
843 protocols = protocols->next;
848 /* Then try the class implementations. */
849 for (cls = self; cls; cls = cls->super_class) {
852 struct objc_method_list *mlist;
853 while ( (mlist = _class_inlinedNextMethodList( cls, &iterator )) ) {
854 for (i = 0; i < mlist->method_count; i++)
855 if (mlist->method_list[i].method_name == aSelector) {
856 struct objc_method_description *m;
857 m = (struct objc_method_description *)&mlist->method_list[i];
867 /* Obsolete methods (for binary compatibility only). */
871 return [self superclass];
876 return [self superclass];
879 - (BOOL)isKindOfGivenName:(const char *)aClassName
881 return [self isKindOfClassNamed: aClassName];
884 - (BOOL)isMemberOfGivenName:(const char *)aClassName
886 return [self isMemberOfClassNamed: aClassName];
889 - (struct objc_method_description *) methodDescFor:(SEL)aSelector
891 return [self descriptionForMethod: aSelector];
894 + (struct objc_method_description *) instanceMethodDescFor:(SEL)aSelector
896 return [self descriptionForInstanceMethod: aSelector];
899 - findClass:(const char *)aClassName
901 return (*_cvtToId)(aClassName);
904 - shouldNotImplement:(SEL)aSelector
906 return [self error:_errShouldNotImp, sel_getName(aSelector)];
911 static id _internal_object_copyFromZone(Object *anObject, unsigned nBytes, void *z)
914 register unsigned siz;
919 obj = (*_zoneAlloc)(anObject->isa, nBytes, z);
920 siz = ((struct objc_class *)anObject->isa)->instance_size + nBytes;
921 bcopy((const char*)anObject, (char*)obj, siz);
925 static id _internal_object_copy(Object *anObject, unsigned nBytes)
927 void *z= malloc_zone_from_ptr(anObject);
928 return _internal_object_copyFromZone(anObject,
930 z ? z : malloc_default_zone());
933 static id _internal_object_dispose(Object *anObject)
935 if (anObject==nil) return nil;
936 anObject->isa = _objc_getFreedObjectClass ();
941 static id _internal_object_reallocFromZone(Object *anObject, unsigned nBytes, void *z)
944 struct objc_class * tmp;
947 __objc_error(nil, _errReAllocNil, 0);
949 if (anObject->isa == _objc_getFreedObjectClass ())
950 __objc_error(anObject, _errReAllocFreed, 0);
952 if (nBytes < ((struct objc_class *)anObject->isa)->instance_size)
953 __objc_error(anObject, _errReAllocTooSmall,
954 object_getClassName(anObject), nBytes);
956 // Make sure not to modify space that has been declared free
958 anObject->isa = _objc_getFreedObjectClass ();
959 newObject = (Object*)malloc_zone_realloc(z, (void*)anObject, (size_t)nBytes);
961 newObject->isa = tmp;
966 __objc_error(anObject, _errNoMem,
967 object_getClassName(anObject), nBytes);
972 static id _internal_object_realloc(Object *anObject, unsigned nBytes)
974 void *z= malloc_zone_from_ptr(anObject);
975 return _internal_object_reallocFromZone(anObject,
977 z ? z : malloc_default_zone());
980 /* Functional Interface to system primitives */
982 id object_copy(Object *anObject, unsigned nBytes)
984 return (*_copy)(anObject, nBytes);
987 id object_copyFromZone(Object *anObject, unsigned nBytes, void *z)
989 return (*_zoneCopy)(anObject, nBytes, z);
992 id object_dispose(Object *anObject)
994 return (*_dealloc)(anObject);
997 id object_realloc(Object *anObject, unsigned nBytes)
999 return (*_realloc)(anObject, nBytes);
1002 id object_reallocFromZone(Object *anObject, unsigned nBytes, void *z)
1004 return (*_zoneRealloc)(anObject, nBytes, z);
1007 Ivar object_setInstanceVariable(id obj, const char *name, void *value)
1014 if ((ivar = class_getInstanceVariable(((Object*)obj)->isa, name))) {
1015 ivaridx = (void **)((char *)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;