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.
30 #include <winnt-pdo.h>
33 #ifdef NeXT_PDO // pickup BUG fix flags
37 #import <objc/Object.h>
38 #import "objc-private.h"
39 #import <objc/objc-runtime.h>
40 #import <objc/Protocol.h>
44 OBJC_EXPORT id (*_cvtToId)(const char *);
45 OBJC_EXPORT id (*_poseAs)();
47 #define ISMETA(cls) (((struct objc_class *)cls)->info & CLS_META)
51 _errNoMem[] = "failed -- out of memory(%s, %u)",
52 _errReAllocNil[] = "reallocating nil object",
53 _errReAllocFreed[] = "reallocating freed object",
54 _errReAllocTooSmall[] = "(%s, %u) requested size too small",
55 _errShouldHaveImp[] = "should have implemented the '%s' method.",
56 _errShouldNotImp[] = "should NOT have implemented the '%s' method.",
57 _errLeftUndone[] = "method '%s' not implemented",
58 _errBadSel[] = "method %s given invalid selector %s",
59 _errDoesntRecognize[] = "does not recognize selector %c%s";
62 @implementation Object
77 return (*_poseAs)(self, aFactory);
82 id newObject = (*_alloc)((Class)self, 0);
83 struct objc_class * metaClass = ((struct objc_class *) self)->isa;
84 if (metaClass->version > 1)
85 return [newObject init];
92 return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());
95 + allocFromZone:(void *) z
97 return (*_zoneAlloc)((Class)self, 0, z);
107 return ((struct objc_class *)isa)->name;
112 return ((struct objc_class *)self)->name;
117 return ((uarith_t)self) >> 2;
120 - (BOOL)isEqual:anObject
122 return anObject == self;
127 return (*_dealloc)(self);
152 void *z = malloc_zone_from_ptr(self);
153 return z ? z : malloc_default_zone();
158 return ((struct objc_class *)self)->super_class;
163 return ((struct objc_class *)isa)->super_class;
168 struct objc_class * class = (struct objc_class *) self;
169 return class->version;
172 + setVersion: (int) aVersion
174 struct objc_class * class = (struct objc_class *) self;
175 class->version = aVersion;
179 - (BOOL)isKindOf:aClass
182 for (cls = isa; cls; cls = ((struct objc_class *)cls)->super_class)
183 if (cls == (Class)aClass)
188 - (BOOL)isMemberOf:aClass
190 return isa == (Class)aClass;
193 - (BOOL)isKindOfClassNamed:(const char *)aClassName
196 for (cls = isa; cls; cls = ((struct objc_class *)cls)->super_class)
197 if (strcmp(aClassName, ((struct objc_class *)cls)->name) == 0)
202 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
204 return strcmp(aClassName, ((struct objc_class *)isa)->name) == 0;
207 + (BOOL)instancesRespondTo:(SEL)aSelector
209 return class_respondsToMethod((Class)self, aSelector);
212 - (BOOL)respondsTo:(SEL)aSelector
214 return class_respondsToMethod(isa, aSelector);
219 return [self copyFromZone: [self zone]];
222 - copyFromZone:(void *)z
224 return (*_zoneCopy)(self, 0, z);
227 - (IMP)methodFor:(SEL)aSelector
229 return class_lookupMethod(isa, aSelector);
232 + (IMP)instanceMethodFor:(SEL)aSelector
234 return class_lookupMethod(self, aSelector);
237 #if defined(__alpha__)
238 #define MAX_RETSTRUCT_SIZE 256
240 typedef struct _foolGCC {
241 char c[MAX_RETSTRUCT_SIZE];
244 typedef _variableStruct (*callReturnsStruct)();
246 OBJC_EXPORT long sizeOfReturnedStruct(char **);
248 long sizeOfType(char **pp)
251 long stack_size = 0, n = 0;
255 stack_size += sizeof(char); // Alignment ?
259 stack_size += sizeof(short);// Alignment ?
264 stack_size += sizeof(int);
268 stack_size += sizeof(long int);
271 stack_size += sizeof(float);
274 stack_size += sizeof(double);
280 stack_size += sizeof(char*);
283 stack_size += sizeOfReturnedStruct(&p);
289 n = 10 * n + (*p++ - '0');
290 stack_size += (n * sizeOfType(&p));
300 sizeOfReturnedStruct(char **pp)
303 long stack_size = 0, n = 0;
304 while(p!=NULL && *++p!='=') ; // skip the struct name
305 while(p!=NULL && *++p!='}')
306 stack_size += sizeOfType(&p);
307 return stack_size + 8; // Add 8 as a 'forfait value'
308 // to take alignment into account
311 - perform:(SEL)aSelector
315 _variableStruct *dummyRetVal;
319 method = class_getInstanceMethod((Class)self->isa,
322 method = class_getClassMethod((Class)self->isa,
325 p = &method->method_types[0];
327 // Method returns a structure
328 stack_size = sizeOfReturnedStruct(&p);
329 if(stack_size<MAX_RETSTRUCT_SIZE)
332 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
333 // return structures whose size is not grater than
334 // MAX_RETSTRUCT_SIZE.
335 // This is because the compiler allocates space on the stack
336 // for the size of the return structure, and when the method
337 // returns, the structure is copied on the space allocated
338 // on the stack: if the structure is greater than the space
339 // allocated... bang! (the stack is gone:-)
341 ((callReturnsStruct)objc_msgSend)(self, aSelector);
345 dummyRetVal = (_variableStruct*) malloc(stack_size);
347 // Following asm code is equivalent to:
348 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector);
350 asm("ldq $16,%0":"=g" (dummyRetVal):);
351 asm("ldq $17,%0":"=g" (self):);
352 asm("ldq $18,%0":"=g" (aSelector):);
353 asm("bis $31,1,$25");
354 asm("lda $27,objc_msgSend");
355 asm("jsr $26,($27),objc_msgSend");
356 asm("ldgp $29,0($26)");
358 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector);
362 // When the method return a structure, we cannot return it here
363 // becuse we're not called in the right way, so we must return
364 // something else: wether it is self or NULL is a matter of taste.
368 // We fall back here either because the method doesn't return
369 // a structure, or because method is NULL: in this latter
370 // case the call to msgSend will try to forward the message.
371 return objc_msgSend(self, aSelector);
374 // We fallback here only when aSelector is NULL
375 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
378 - perform:(SEL)aSelector with:anObject
382 _variableStruct *dummyRetVal;
386 method = class_getInstanceMethod((Class)self->isa,
389 method = class_getClassMethod((Class)self->isa,
392 p = &method->method_types[0];
394 // Method returns a structure
395 stack_size = sizeOfReturnedStruct(&p);
396 if(stack_size<MAX_RETSTRUCT_SIZE)
399 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
400 // return structures whose size is not grater than
401 // MAX_RETSTRUCT_SIZE.
402 // This is because the compiler allocates space on the stack
403 // for the size of the return structure, and when the method
404 // returns, the structure is copied on the space allocated
405 // on the stack: if the structure is greater than the space
406 // allocated... bang! (the stack is gone:-)
408 ((callReturnsStruct)objc_msgSend)(self, aSelector, anObject);
412 dummyRetVal = (_variableStruct*) malloc(stack_size);
414 // Following asm code is equivalent to:
415 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,anObject);
417 asm("ldq $16,%0":"=g" (dummyRetVal):);
418 asm("ldq $17,%0":"=g" (self):);
419 asm("ldq $18,%0":"=g" (aSelector):);
420 asm("ldq $19,%0":"=g" (anObject):);
421 asm("bis $31,1,$25");
422 asm("lda $27,objc_msgSend");
423 asm("jsr $26,($27),objc_msgSend");
424 asm("ldgp $29,0($26)");
426 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,anObject);
430 // When the method return a structure, we cannot return it here
431 // becuse we're not called in the right way, so we must return
432 // something else: wether it is self or NULL is a matter of taste.
436 // We fall back here either because the method doesn't return
437 // a structure, or because method is NULL: in this latter
438 // case the call to msgSend will try to forward the message.
439 return objc_msgSend(self, aSelector, anObject);
442 // We fallback here only when aSelector is NULL
443 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
446 - perform:(SEL)aSelector with:obj1 with:obj2
450 _variableStruct *dummyRetVal;
454 method = class_getInstanceMethod((Class)self->isa,
457 method = class_getClassMethod((Class)self->isa,
460 p = &method->method_types[0];
462 // Method returns a structure
463 stack_size = sizeOfReturnedStruct(&p);
464 if(stack_size<MAX_RETSTRUCT_SIZE)
467 // The MAX_RETSTRUCT_SIZE value allow us to support methods that
468 // return structures whose size is not grater than
469 // MAX_RETSTRUCT_SIZE.
470 // This is because the compiler allocates space on the stack
471 // for the size of the return structure, and when the method
472 // returns, the structure is copied on the space allocated
473 // on the stack: if the structure is greater than the space
474 // allocated... bang! (the stack is gone:-)
476 ((callReturnsStruct)objc_msgSend)(self, aSelector, obj1, obj2);
480 dummyRetVal = (_variableStruct*) malloc(stack_size);
482 // Following asm code is equivalent to:
483 // *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,obj1,obj2);
486 asm("ldq $16,%0":"=g" (dummyRetVal):);
487 asm("ldq $17,%0":"=g" (self):);
488 asm("ldq $18,%0":"=g" (aSelector):);
489 asm("ldq $19,%0":"=g" (obj1):);
490 asm("ldq $20,%0":"=g" (obj2):);
491 asm("bis $31,1,$25");
492 asm("lda $27,objc_msgSend");
493 asm("jsr $26,($27),objc_msgSend");
494 asm("ldgp $29,0($26)");
496 *dummyRetVal=((callReturnsStruct)objc_msgSend)(self,aSelector,obj1,obj2);
500 // When the method return a structure, we cannot return it here
501 // becuse we're not called in the right way, so we must return
502 // something else: wether it is self or NULL is a matter of taste.
506 // We fall back here either because the method doesn't return
507 // a structure, or because method is NULL: in this latter
508 // case the call to msgSend will try to forward the message.
509 return objc_msgSend(self, aSelector, obj1, obj2);
512 // We fallback here only when aSelector is NULL
513 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
517 - perform:(SEL)aSelector
520 return objc_msgSend(self, aSelector);
522 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
525 - perform:(SEL)aSelector with:anObject
528 return objc_msgSend(self, aSelector, anObject);
530 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
533 - perform:(SEL)aSelector with:obj1 with:obj2
536 return objc_msgSend(self, aSelector, obj1, obj2);
538 return [self error:_errBadSel, SELNAME(_cmd), aSelector];
542 - subclassResponsibility:(SEL)aSelector
544 return [self error:_errShouldHaveImp, sel_getName(aSelector)];
547 - notImplemented:(SEL)aSelector
549 return [self error:_errLeftUndone, sel_getName(aSelector)];
552 - doesNotRecognize:(SEL)aMessage
554 return [self error:_errDoesntRecognize,
555 ISMETA (isa) ? '+' : '-', SELNAME(aMessage)];
558 - error:(const char *)aCStr, ...
562 (*_error)(self, aCStr, ap);
563 _objc_error (self, aCStr, ap); /* In case (*_error)() returns. */
568 - (void) printForDebugger:(void *)stream
572 - write:(void *) stream
577 - read:(void *) stream
582 - forward: (SEL) sel : (marg_list) args
584 return [self doesNotRecognize: sel];
587 /* this method is not part of the published API */
589 - (unsigned)methodArgSize:(SEL)sel
591 Method method = class_getInstanceMethod((Class)isa, sel);
592 if (! method) return 0;
593 return method_getSizeOfArguments(method);
596 #if defined(__alpha__)
599 unsigned long int i16;
600 unsigned long int i17;
601 unsigned long int i18;
602 unsigned long int i19;
603 unsigned long int i20;
604 unsigned long int i21;
605 unsigned long int i25;
606 unsigned long int f16;
607 unsigned long int f17;
608 unsigned long int f18;
609 unsigned long int f19;
610 unsigned long int f20;
611 unsigned long int f21;
612 unsigned long int sp;
615 - performv: (SEL) sel : (marg_list) args
620 unsigned long int size;
621 char scratchMem[MAX_RETSTRUCT_SIZE];
624 // Messages to nil object always return nil
625 if (! self) return nil;
627 // Got to have a selector
629 return [self error:_errBadSel, SELNAME(_cmd), sel];
631 // Handle a method which returns a structure and
632 // has been called as such
633 if (((_m_args_p)args)->i25){
634 // Calculate size of the marg_list from the method's
635 // signature. This looks for the method in self
636 // and its superclasses.
637 size = [self methodArgSize: sel];
639 // If neither self nor its superclasses implement
640 // the method, forward the message because self
641 // might know someone who does. This is a
642 // "chained" forward...
643 if (! size) return [self forward: sel: args];
645 // Message self with the specified selector and arguments
646 return objc_msgSendv (self, sel, size, args);
649 // Look for instance method in self's class and superclasses
650 method = class_getInstanceMethod((Class)self->isa,sel);
652 // Look for class method in self's class and superclass
654 method = class_getClassMethod((Class)self->isa,sel);
656 // If neither self nor its superclasses implement
657 // the method, forward the message because self
658 // might know someone who does. This is a
659 // "chained" forward...
661 return [self forward: sel: args];
663 // Calculate size of the marg_list from the method's
665 size = method_getSizeOfArguments(method);
667 // Ready to send message now if the return type
668 // is not a structure
669 p = &method->method_types[0];
671 return objc_msgSendv(self, sel, size, args);
673 // Method returns a structure
674 stack_size = sizeOfReturnedStruct(&p);
675 if(stack_size>=MAX_RETSTRUCT_SIZE)
676 scratchMemP = (char*)malloc(stack_size);
678 scratchMemP = &scratchMem[0];
680 // Set i25 so objc_msgSendv will know that method returns a structure
681 ((_m_args_p)args)->i25 = 1;
683 // Set first param of method to be called to safe return address
684 ((_m_args_p)args)->i16 = (unsigned long int) scratchMemP;
685 objc_msgSendv(self, sel, size, args);
687 if(stack_size>=MAX_RETSTRUCT_SIZE)
693 - performv: (SEL) sel : (marg_list) args
699 // Save ret0 so methods that return a struct might work.
700 asm("copy %%r28, %0": "=r"(ret): );
703 // Messages to nil object always return nil
704 if (! self) return nil;
706 // Calculate size of the marg_list from the method's
707 // signature. This looks for the method in self
708 // and its superclasses.
709 size = [self methodArgSize: sel];
711 // If neither self nor its superclasses implement
712 // it, forward the message because self might know
713 // someone who does. This is a "chained" forward...
714 if (! size) return [self forward: sel: args];
717 // Unfortunately, it looks like the compiler puts something else in
718 // r28 right after this instruction, so this is all for naught.
719 asm("copy %0, %%r28": : "r"(ret));
722 // Message self with the specified selector and arguments
723 return objc_msgSendv (self, sel, size, args);
727 /* Testing protocol conformance */
729 - (BOOL) conformsTo: (Protocol *)aProtocolObj
731 return [(id)isa conformsTo:aProtocolObj];
734 + (BOOL) conformsTo: (Protocol *)aProtocolObj
736 struct objc_class * class;
738 for (class = self; class; class = class->super_class)
740 if (class->isa->version >= 3)
742 struct objc_protocol_list *protocols = class->protocols;
748 for (i = 0; i < protocols->count; i++)
750 Protocol *p = protocols->list[i];
752 if ([p conformsTo:aProtocolObj])
756 if (class->isa->version <= 4)
759 protocols = protocols->next;
767 /* Looking up information for a method */
769 - (struct objc_method_description *) descriptionForMethod:(SEL)aSelector
771 struct objc_class * cls;
772 struct objc_method_description *m;
774 /* Look in the protocols first. */
775 for (cls = isa; cls; cls = cls->super_class)
777 if (cls->isa->version >= 3)
779 struct objc_protocol_list *protocols = cls->protocols;
785 for (i = 0; i < protocols->count; i++)
787 Protocol *p = protocols->list[i];
790 m = [p descriptionForClassMethod:aSelector];
792 m = [p descriptionForInstanceMethod:aSelector];
799 if (cls->isa->version <= 4)
802 protocols = protocols->next;
807 /* Then try the class implementations. */
808 for (cls = isa; cls; cls = cls->super_class) {
811 struct objc_method_list *mlist;
812 while ( (mlist = _class_inlinedNextMethodList( cls, &iterator )) ) {
813 for (i = 0; i < mlist->method_count; i++)
814 if (mlist->method_list[i].method_name == aSelector) {
815 struct objc_method_description *m;
816 m = (struct objc_method_description *)&mlist->method_list[i];
825 + (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSelector
827 struct objc_class * cls;
829 /* Look in the protocols first. */
830 for (cls = self; cls; cls = cls->super_class)
832 if (cls->isa->version >= 3)
834 struct objc_protocol_list *protocols = cls->protocols;
840 for (i = 0; i < protocols->count; i++)
842 Protocol *p = protocols->list[i];
843 struct objc_method_description *m;
845 if ((m = [p descriptionForInstanceMethod:aSelector]))
849 if (cls->isa->version <= 4)
852 protocols = protocols->next;
857 /* Then try the class implementations. */
858 for (cls = self; cls; cls = cls->super_class) {
861 struct objc_method_list *mlist;
862 while ( (mlist = _class_inlinedNextMethodList( cls, &iterator )) ) {
863 for (i = 0; i < mlist->method_count; i++)
864 if (mlist->method_list[i].method_name == aSelector) {
865 struct objc_method_description *m;
866 m = (struct objc_method_description *)&mlist->method_list[i];
876 /* Obsolete methods (for binary compatibility only). */
880 return [self superclass];
885 return [self superclass];
888 - (BOOL)isKindOfGivenName:(const char *)aClassName
890 return [self isKindOfClassNamed: aClassName];
893 - (BOOL)isMemberOfGivenName:(const char *)aClassName
895 return [self isMemberOfClassNamed: aClassName];
898 - (struct objc_method_description *) methodDescFor:(SEL)aSelector
900 return [self descriptionForMethod: aSelector];
903 + (struct objc_method_description *) instanceMethodDescFor:(SEL)aSelector
905 return [self descriptionForInstanceMethod: aSelector];
908 - findClass:(const char *)aClassName
910 return (*_cvtToId)(aClassName);
913 - shouldNotImplement:(SEL)aSelector
915 return [self error:_errShouldNotImp, sel_getName(aSelector)];
920 static id _internal_object_copyFromZone(Object *anObject, unsigned nBytes, void *z)
923 register unsigned siz;
928 obj = (*_zoneAlloc)(anObject->isa, nBytes, z);
929 siz = ((struct objc_class *)anObject->isa)->instance_size + nBytes;
930 bcopy((const char*)anObject, (char*)obj, siz);
934 static id _internal_object_copy(Object *anObject, unsigned nBytes)
936 void *z= malloc_zone_from_ptr(anObject);
937 return _internal_object_copyFromZone(anObject,
939 z ? z : malloc_default_zone());
942 static id _internal_object_dispose(Object *anObject)
944 if (anObject==nil) return nil;
945 anObject->isa = _objc_getFreedObjectClass ();
950 static id _internal_object_reallocFromZone(Object *anObject, unsigned nBytes, void *z)
953 struct objc_class * tmp;
956 __objc_error(nil, _errReAllocNil, 0);
958 if (anObject->isa == _objc_getFreedObjectClass ())
959 __objc_error(anObject, _errReAllocFreed, 0);
961 if (nBytes < ((struct objc_class *)anObject->isa)->instance_size)
962 __objc_error(anObject, _errReAllocTooSmall,
963 object_getClassName(anObject), nBytes);
965 // Make sure not to modify space that has been declared free
967 anObject->isa = _objc_getFreedObjectClass ();
968 newObject = (Object*)malloc_zone_realloc(z, (void*)anObject, (size_t)nBytes);
970 newObject->isa = tmp;
975 __objc_error(anObject, _errNoMem,
976 object_getClassName(anObject), nBytes);
981 static id _internal_object_realloc(Object *anObject, unsigned nBytes)
983 void *z= malloc_zone_from_ptr(anObject);
984 return _internal_object_reallocFromZone(anObject,
986 z ? z : malloc_default_zone());
989 /* Functional Interface to system primitives */
991 id object_copy(Object *anObject, unsigned nBytes)
993 return (*_copy)(anObject, nBytes);
996 id object_copyFromZone(Object *anObject, unsigned nBytes, void *z)
998 return (*_zoneCopy)(anObject, nBytes, z);
1001 id object_dispose(Object *anObject)
1003 return (*_dealloc)(anObject);
1006 id object_realloc(Object *anObject, unsigned nBytes)
1008 return (*_realloc)(anObject, nBytes);
1011 id object_reallocFromZone(Object *anObject, unsigned nBytes, void *z)
1013 return (*_zoneRealloc)(anObject, nBytes, z);
1016 Ivar object_setInstanceVariable(id obj, const char *name, void *value)
1023 if ((ivar = class_getInstanceVariable(((Object*)obj)->isa, name))) {
1024 ivaridx = (void **)((char *)obj + ivar->ivar_offset);
1031 Ivar object_getInstanceVariable(id obj, const char *name, void **value)
1038 if ((ivar = class_getInstanceVariable(((Object*)obj)->isa, name))) {
1039 ivaridx = (void **)((char *)obj + ivar->ivar_offset);
1047 #if defined(__hpux__)
1048 id (*_objc_msgSend_v)(id, SEL, ...) = objc_msgSend;
1051 id (*_copy)(id, unsigned) = _internal_object_copy;
1052 id (*_realloc)(id, unsigned) = _internal_object_realloc;
1053 id (*_dealloc)(id) = _internal_object_dispose;
1054 id (*_cvtToId)(const char *)= objc_lookUpClass;
1055 SEL (*_cvtToSel)(const char *)= sel_getUid;
1056 void (*_error)() = (void(*)())_objc_error;
1057 id (*_zoneCopy)(id, unsigned, void *) = _internal_object_copyFromZone;
1058 id (*_zoneRealloc)(id, unsigned, void *) = _internal_object_reallocFromZone;