Annotation of objc/Object.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      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.0 (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
                     12:  * this file.
                     13:  * 
                     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
                     20:  * under the License."
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: /*
                     25:        Object.m
                     26:        Copyright 1988, 1989 NeXT, Inc.
                     27: */
                     28: 
                     29: #ifdef SHLIB
                     30: #import "shlib.h"
                     31: #endif SHLIB
                     32: 
                     33: #import "objc-private.h"
                     34: #import <stdarg.h> 
                     35: #import <string.h> 
                     36: 
                     37: #import "objc-runtime.h"       
                     38: #import "typedstream.h"
                     39: #import "Protocol.h"
                     40: 
                     41: extern id (*_cvtToId)(const char *);
                     42: extern id (*_poseAs)();
                     43: 
                     44: #define ISMETA(cls)            ((cls)->info & CLS_META) 
                     45: 
                     46: // Error Messages
                     47: static const char
                     48:        _errNoMem[] = "failed -- out of memory(%s, %u)",
                     49:        _errReAllocNil[] = "reallocating nil object",
                     50:        _errReAllocFreed[] = "reallocating freed object",
                     51:        _errReAllocTooSmall[] = "(%s, %u) requested size too small",
                     52:        _errShouldHaveImp[] = "should have implemented the '%s' method.",
                     53:        _errShouldNotImp[] = "should NOT have implemented the '%s' method.",
                     54:        _errLeftUndone[] = "method '%s' not implemented",
                     55:        _errBadSel[] = "method %s given invalid selector %s",
                     56:        _errDoesntRecognize[] = "does not recognize selector %c%s";
                     57: 
                     58: #import "Object.h"
                     59: 
                     60: @implementation Object 
                     61: 
                     62: 
                     63: + initialize
                     64: {
                     65:        return self; 
                     66: }
                     67: 
                     68: - awake 
                     69: {
                     70:        return self; 
                     71: }
                     72: 
                     73: + poseAs: aFactory
                     74: { 
                     75:        return (*_poseAs)(self, aFactory); 
                     76: }
                     77: 
                     78: + new
                     79: {
                     80:        id newObject = (*_alloc)((Class)self, 0);
                     81:        Class metaClass = ((Class) self)->isa;
                     82:        if (metaClass->version > 1)
                     83:            return [newObject init];
                     84:        else
                     85:            return newObject;
                     86: }
                     87: 
                     88: + alloc
                     89: {
                     90:        return (*_zoneAlloc)((Class)self, 0, NXDefaultMallocZone()); 
                     91: }
                     92: 
                     93: + allocFromZone:(NXZone *) zone
                     94: {
                     95:        return (*_zoneAlloc)((Class)self, 0, zone); 
                     96: }
                     97: 
                     98: - init
                     99: {
                    100:     return self;
                    101: }
                    102: 
                    103: - (const char *)name
                    104: {
                    105:        return isa->name; 
                    106: }
                    107: 
                    108: + (const char *)name
                    109: {
                    110:        return ((Class)self)->name; 
                    111: }
                    112: 
                    113: - (unsigned)hash
                    114: {
                    115:        return ((unsigned)self) >> 2; 
                    116: }
                    117: 
                    118: - (BOOL)isEqual:anObject
                    119: {
                    120:        return anObject == self; 
                    121: }
                    122: 
                    123: - free 
                    124: { 
                    125:        return (*_dealloc)(self); 
                    126: }
                    127: 
                    128: + free
                    129: {
                    130:        return nil; 
                    131: }
                    132: 
                    133: - self
                    134: {
                    135:        return self; 
                    136: }
                    137: 
                    138: - class
                    139: {
                    140:        return (id)isa; 
                    141: }
                    142: 
                    143: + class 
                    144: {
                    145:        return self;
                    146: }
                    147: 
                    148: - (NXZone *)zone
                    149: {
                    150:        NXZone *zone = NXZoneFromPtr(self);
                    151:        return zone ? zone : NXDefaultMallocZone();
                    152: }
                    153: 
                    154: + superclass 
                    155: { 
                    156:        return ((Class)self)->super_class; 
                    157: }
                    158: 
                    159: - superclass 
                    160: { 
                    161:        return isa->super_class; 
                    162: }
                    163: 
                    164: + (int) version
                    165: {
                    166:        Class   class = (Class) self;
                    167:        return class->version;
                    168: }
                    169: 
                    170: + setVersion: (int) aVersion
                    171: {
                    172:        Class   class = (Class) self;
                    173:        class->version = aVersion;
                    174:        return self;
                    175: }
                    176: 
                    177: - (BOOL)isKindOf:aClass
                    178: {
                    179:        register Class cls;
                    180:        for (cls = isa; cls; cls = cls->super_class) 
                    181:                if (cls == (Class)aClass)
                    182:                        return YES;
                    183:        return NO;
                    184: }
                    185: 
                    186: - (BOOL)isMemberOf:aClass
                    187: {
                    188:        return isa == (Class)aClass;
                    189: }
                    190: 
                    191: - (BOOL)isKindOfClassNamed:(const char *)aClassName
                    192: {
                    193:        register Class cls;
                    194:        for (cls = isa; cls; cls = cls->super_class) 
                    195:                if (strcmp(aClassName, cls->name) == 0)
                    196:                        return YES;
                    197:        return NO;
                    198: }
                    199: 
                    200: - (BOOL)isMemberOfClassNamed:(const char *)aClassName 
                    201: {
                    202:        return strcmp(aClassName, isa->name) == 0;
                    203: }
                    204: 
                    205: + (BOOL)instancesRespondTo:(SEL)aSelector 
                    206: {
                    207:        return class_respondsToMethod((Class)self, aSelector);
                    208: }
                    209: 
                    210: - (BOOL)respondsTo:(SEL)aSelector 
                    211: {
                    212:        return class_respondsToMethod(isa, aSelector);
                    213: }
                    214: 
                    215: - copy 
                    216: {
                    217:        return [self copyFromZone: [self zone]];
                    218: }
                    219: 
                    220: - copyFromZone:(NXZone *)zone
                    221: {
                    222:        return (*_zoneCopy)(self, 0, zone); 
                    223: }
                    224: 
                    225: - (IMP)methodFor:(SEL)aSelector 
                    226: {
                    227:        return class_lookupMethod(isa, aSelector);
                    228: }
                    229: 
                    230: + (IMP)instanceMethodFor:(SEL)aSelector 
                    231: {
                    232:        return class_lookupMethod(self, aSelector);
                    233: }
                    234: 
                    235: - perform:(SEL)aSelector 
                    236: { 
                    237:        if (aSelector)
                    238:                return objc_msgSend(self, aSelector); 
                    239:        else
                    240:                return [self error:_errBadSel, SELNAME(_cmd), aSelector];
                    241: }
                    242: 
                    243: - perform:(SEL)aSelector with:anObject 
                    244: {
                    245:        if (aSelector)
                    246:                return objc_msgSend(self, aSelector, anObject); 
                    247:        else
                    248:                return [self error:_errBadSel, SELNAME(_cmd), aSelector];
                    249: }
                    250: 
                    251: - perform:(SEL)aSelector with:obj1 with:obj2 
                    252: {
                    253:        if (aSelector)
                    254:                return objc_msgSend(self, aSelector, obj1, obj2); 
                    255:        else
                    256:                return [self error:_errBadSel, SELNAME(_cmd), aSelector];
                    257: }
                    258: 
                    259: - subclassResponsibility:(SEL)aSelector 
                    260: {
                    261:        return [self error:_errShouldHaveImp, sel_getName(aSelector)];
                    262: }
                    263: 
                    264: - notImplemented:(SEL)aSelector
                    265: {
                    266:        return [self error:_errLeftUndone, sel_getName(aSelector)];
                    267: }
                    268: 
                    269: - doesNotRecognize:(SEL)aMessage
                    270: {
                    271:        return [self error:_errDoesntRecognize, 
                    272:                ISMETA (isa) ? '+' : '-', SELNAME(aMessage)];
                    273: }
                    274: 
                    275: - error:(const char *)aCStr, ... 
                    276: {
                    277:        va_list ap;
                    278:        va_start(ap,aCStr); 
                    279:        (*_error)(self, aCStr, ap); 
                    280:        _objc_error (self, aCStr, ap);  /* In case (*_error)() returns. */
                    281:        va_end(ap);
                    282:         return nil;
                    283: }
                    284: 
                    285: - (void) printForDebugger:(NXStream *)stream
                    286: {
                    287:        NXPrintf (stream, "<%s: 0x%x>", object_getClassName (self), self);
                    288:        NXFlush (stream);
                    289: }
                    290: 
                    291: - write:(NXTypedStream *) stream 
                    292: {
                    293:        return self;
                    294: }
                    295: 
                    296: - read:(NXTypedStream *) stream 
                    297: {
                    298:        return self;
                    299: }
                    300: 
                    301: - forward: (SEL) sel : (marg_list) args 
                    302: {
                    303:     return [self doesNotRecognize: sel];
                    304: }
                    305: 
                    306: /* this method is not part of the published API */
                    307: 
                    308: - (unsigned)methodArgSize:(SEL)sel 
                    309: {
                    310:     Method     method = class_getInstanceMethod((Class)isa, sel);
                    311:     if (! method) return 0;
                    312:     return method_getSizeOfArguments(method);
                    313: }
                    314: 
                    315: - performv: (SEL) sel : (marg_list) args 
                    316: {
                    317:     unsigned   size;
                    318: #if hppa && 0
                    319:     void *ret;
                    320:    
                    321:     // Save ret0 so methods that return a struct might work.
                    322:     asm("copy %%r28, %0": "=r"(ret): );
                    323: #endif hppa
                    324: 
                    325:     if (! self) return nil;
                    326:     size = [self methodArgSize: sel];
                    327:     if (! size) return [self doesNotRecognize: sel];
                    328: 
                    329: #if hppa && 0
                    330:     // Unfortunately, it looks like the compiler puts something else in
                    331:     // r28 right after this instruction, so this is all for naught.
                    332:     asm("copy %0, %%r28": : "r"(ret));
                    333: #endif hppa
                    334: 
                    335:     return objc_msgSendv (self, sel, size, args); 
                    336: }
                    337: 
                    338: /* Testing protocol conformance */
                    339: 
                    340: - (BOOL) conformsTo: (Protocol *)aProtocolObj
                    341: {
                    342:   return [isa conformsTo:aProtocolObj];
                    343: }
                    344: 
                    345: + (BOOL) conformsTo: (Protocol *)aProtocolObj
                    346: {
                    347:   Class class;
                    348: 
                    349:   for (class = self; class; class = class->super_class)
                    350:     {
                    351:       if (class->isa->version >= 3)
                    352:         {
                    353:          struct objc_protocol_list *protocols = class->protocols;
                    354: 
                    355:          while (protocols)
                    356:            {
                    357:              int i;
                    358: 
                    359:              for (i = 0; i < protocols->count; i++)
                    360:                {
                    361:                  Protocol *p = protocols->list[i];
                    362:     
                    363:                  if ([p conformsTo:aProtocolObj])
                    364:                    return YES;
                    365:                }
                    366: 
                    367:              if (class->isa->version <= 4)
                    368:                break;
                    369: 
                    370:              protocols = protocols->next;
                    371:            }
                    372:        }
                    373:     }
                    374:   return NO;
                    375: }
                    376: 
                    377: #if hppa && 0
                    378: #define OBJC_REMOTE_SIGN_BUG 1
                    379: #endif
                    380: 
                    381: #if OBJC_REMOTE_SIGN_BUG
                    382: /*
                    383:  * The problem being worked around here is the one where NextStep DO 
                    384:  * (actually ObjC) can't handle minus signs in method descriptor strings sent
                    385:  * by HP clients.  We remove them here, but this code returns the wrong 
                    386:  * answer for local clients.
                    387:  * 
                    388:  * The bug needs to get fixed in NextStep. This workaround is really ugly.
                    389:  */
                    390: static char *
                    391: stripsigns(char *str)
                    392: {
                    393:     char *dst;
                    394:     char *src;
                    395: 
                    396:     if (str) {
                    397:        dst = src = str;
                    398:        while (*src) {
                    399:            if (*src == '-')  {
                    400:                src++;  /* skip minus sign */
                    401:            } else {
                    402:                *dst++ = *src++;        /* copy */
                    403:            }
                    404:        }
                    405:        *dst = 0;
                    406:     }
                    407:     return (str);
                    408: }
                    409: #endif /* OBJC_REMOTE_SIGN_BUG */
                    410: 
                    411: /* Looking up information for a method */
                    412: 
                    413: - (struct objc_method_description *) descriptionForMethod:(SEL)aSelector
                    414: {
                    415:   Class cls;
                    416:   struct objc_method_description *m;
                    417: 
                    418:   /* Look in the protocols first. */
                    419:   for (cls = isa; cls; cls = cls->super_class)
                    420:     {
                    421:       if (cls->isa->version >= 3)
                    422:         {
                    423:          struct objc_protocol_list *protocols = cls->protocols;
                    424:   
                    425:          while (protocols)
                    426:            {
                    427:              int i;
                    428: 
                    429:              for (i = 0; i < protocols->count; i++)
                    430:                {
                    431:                  Protocol *p = protocols->list[i];
                    432: 
                    433:                  if (ISMETA (cls))
                    434:                    m = [p descriptionForClassMethod:aSelector];
                    435:                  else
                    436:                    m = [p descriptionForInstanceMethod:aSelector];
                    437: 
                    438:                  if (m) {
                    439: #if OBJC_REMOTE_SIGN_BUG
                    440: #warning "Working around OBJC_REMOTE_SIGN_BUG"
                    441:                      m->types = stripsigns(m->types);
                    442: #endif /* OBJC_REMOTE_SIGN_BUG */
                    443:                      return m;
                    444:                  }
                    445:                }
                    446:   
                    447:              if (cls->isa->version <= 4)
                    448:                break;
                    449:   
                    450:              protocols = protocols->next;
                    451:            }
                    452:        }
                    453:     }
                    454: 
                    455:   /* Then try the class implementations. */
                    456:   for (cls = isa; cls; cls = cls->super_class)
                    457:     {
                    458:       struct objc_method_list *methods;
                    459: 
                    460:       for (methods = cls->methods; methods; methods = methods->method_next)
                    461:        {
                    462:          int i;
                    463:   
                    464:          for (i = 0; i < methods->method_count; i++)
                    465:            if (methods->method_list[i].method_name == aSelector) {
                    466:              m = (struct objc_method_description *)
                    467:                      &methods->method_list[i];
                    468: #if OBJC_REMOTE_SIGN_BUG
                    469:              m->types = stripsigns(m->types);
                    470: #endif /* OBJC_REMOTE_SIGN_BUG */
                    471:              return (m);
                    472:            }
                    473:        }
                    474:     }
                    475: 
                    476:   return 0;
                    477: }
                    478: 
                    479: + (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSelector
                    480: {
                    481:   Class cls;
                    482: 
                    483:   /* Look in the protocols first. */
                    484:   for (cls = self; cls; cls = cls->super_class)
                    485:     {
                    486:       if (cls->isa->version >= 3)
                    487:         {
                    488:          struct objc_protocol_list *protocols = cls->protocols;
                    489:   
                    490:          while (protocols)
                    491:            {
                    492:              int i;
                    493: 
                    494:              for (i = 0; i < protocols->count; i++)
                    495:                {
                    496:                  Protocol *p = protocols->list[i];
                    497:                  struct objc_method_description *m;
                    498: 
                    499:                  if ((m = [p descriptionForInstanceMethod:aSelector]))
                    500:                    return m;
                    501:                }
                    502:   
                    503:              if (cls->isa->version <= 4)
                    504:                break;
                    505:   
                    506:              protocols = protocols->next;
                    507:            }
                    508:        }
                    509:     }
                    510: 
                    511:   /* Then try the class implementations. */
                    512:   for (cls = self; cls; cls = cls->super_class)
                    513:     {
                    514:       struct objc_method_list *methods;
                    515: 
                    516:       for (methods = cls->methods; methods; methods = methods->method_next)
                    517:        {
                    518:          int i;
                    519:   
                    520:          for (i = 0; i < methods->method_count; i++)
                    521:            if (methods->method_list[i].method_name == aSelector)
                    522:              return (struct objc_method_description *)
                    523:                      &methods->method_list[i];
                    524:        }
                    525:     }
                    526: 
                    527:   return 0;
                    528: }
                    529: 
                    530: 
                    531: /* Obsolete methods (for binary compatibility only). */
                    532: 
                    533: + superClass
                    534: {
                    535:        return [self superclass];
                    536: }
                    537: 
                    538: - superClass
                    539: {
                    540:        return [self superclass];
                    541: }
                    542: 
                    543: - (BOOL)isKindOfGivenName:(const char *)aClassName
                    544: {
                    545:        return [self isKindOfClassNamed: aClassName];
                    546: }
                    547: 
                    548: - (BOOL)isMemberOfGivenName:(const char *)aClassName 
                    549: {
                    550:        return [self isMemberOfClassNamed: aClassName];
                    551: }
                    552: 
                    553: - (struct objc_method_description *) methodDescFor:(SEL)aSelector
                    554: {
                    555:   return [self descriptionForMethod: aSelector];
                    556: }
                    557: 
                    558: + (struct objc_method_description *) instanceMethodDescFor:(SEL)aSelector
                    559: {
                    560:   return [self descriptionForInstanceMethod: aSelector];
                    561: }
                    562: 
                    563: - findClass:(const char *)aClassName
                    564: {
                    565:        return (*_cvtToId)(aClassName);
                    566: }
                    567: 
                    568: - shouldNotImplement:(SEL)aSelector
                    569: {
                    570:        return [self error:_errShouldNotImp, sel_getName(aSelector)];
                    571: }
                    572: 
                    573: @end
                    574: 
                    575: /* System Primitive...declared as `private externs' in shared library */
                    576: 
                    577: id _internal_object_copyFromZone(Object *anObject, unsigned nBytes, NXZone *zone) 
                    578: {
                    579:        id obj;
                    580:        register unsigned siz;
                    581: 
                    582:        if (anObject == nil)
                    583:                return nil;
                    584: 
                    585:        obj = (*_zoneAlloc)(anObject->isa, nBytes, zone);
                    586:        siz = anObject->isa->instance_size + nBytes;
                    587:        bcopy(anObject, obj, siz);
                    588:        return obj;
                    589: }
                    590: 
                    591: id _internal_object_copy(Object *anObject, unsigned nBytes) 
                    592: {
                    593:     NXZone *zone = NXZoneFromPtr(anObject);
                    594:     return _internal_object_copyFromZone(anObject, 
                    595:                                         nBytes,
                    596:                                         zone ? zone : NXDefaultMallocZone());
                    597: }
                    598: 
                    599: id _internal_object_dispose(Object *anObject) 
                    600: {
                    601:        if (anObject==nil) return nil;
                    602:        anObject->isa = _objc_getFreedObjectClass (); 
                    603:        free(anObject);
                    604:        return nil;
                    605: }
                    606: 
                    607: id _internal_object_reallocFromZone(Object *anObject, unsigned nBytes, NXZone *zone) 
                    608: {
                    609:        Object *newObject; 
                    610:        Class tmp;
                    611: 
                    612:        if (anObject == nil)
                    613:                __objc_error(nil, _errReAllocNil, 0);
                    614: 
                    615:        if (anObject->isa == _objc_getFreedObjectClass ())
                    616:                __objc_error(anObject, _errReAllocFreed, 0);
                    617: 
                    618:        if (nBytes < ((Class)anObject->isa)->instance_size)
                    619:                __objc_error(anObject, _errReAllocTooSmall, 
                    620:                                object_getClassName(anObject), nBytes);
                    621: 
                    622:        // Make sure not to modify space that has been declared free
                    623:        tmp = anObject->isa; 
                    624:        anObject->isa = _objc_getFreedObjectClass ();
                    625:        newObject = (id)NXZoneRealloc(zone, anObject, nBytes);
                    626:        if (newObject) {
                    627:                newObject->isa = tmp;
                    628:                return newObject;
                    629:        }
                    630:        else
                    631:             {
                    632:                __objc_error(anObject, _errNoMem, 
                    633:                                object_getClassName(anObject), nBytes);
                    634:                 return nil;
                    635:             }
                    636: }
                    637: 
                    638: id _internal_object_realloc(Object *anObject, unsigned nBytes) 
                    639: {
                    640:     NXZone *zone = NXZoneFromPtr(anObject);
                    641:     return _internal_object_reallocFromZone(anObject,
                    642:                                            nBytes,
                    643:                                            zone ? zone : NXDefaultMallocZone());
                    644: }
                    645: 
                    646: /* Functional Interface to system primitives */
                    647: 
                    648: id object_copy(Object *anObject, unsigned nBytes) 
                    649: {
                    650:        return (*_copy)(anObject, nBytes); 
                    651: }
                    652: 
                    653: id object_copyFromZone(Object *anObject, unsigned nBytes, NXZone *zone) 
                    654: {
                    655:        return (*_zoneCopy)(anObject, nBytes, zone); 
                    656: }
                    657: 
                    658: id object_dispose(Object *anObject) 
                    659: {
                    660:        return (*_dealloc)(anObject); 
                    661: }
                    662: 
                    663: id object_realloc(Object *anObject, unsigned nBytes) 
                    664: {
                    665:        return (*_realloc)(anObject, nBytes); 
                    666: }
                    667: 
                    668: id object_reallocFromZone(Object *anObject, unsigned nBytes, NXZone *zone) 
                    669: {
                    670:        return (*_zoneRealloc)(anObject, nBytes, zone); 
                    671: }
                    672: 
                    673: Ivar object_setInstanceVariable(id obj, const char *name, void *value)
                    674: {
                    675:        Ivar ivar = 0;
                    676: 
                    677:        if (obj && name) {
                    678:                void **ivaridx;
                    679: 
                    680:                if ((ivar = class_getInstanceVariable(((Object*)obj)->isa, name))) {
                    681:                       ivaridx = (void **)((char *)obj + ivar->ivar_offset);
                    682:                       *ivaridx = value;
                    683:                }
                    684:        }
                    685:        return ivar;
                    686: }
                    687: 
                    688: Ivar object_getInstanceVariable(id obj, const char *name, void **value)
                    689: {
                    690:        Ivar ivar = 0;
                    691: 
                    692:        if (obj && name) {
                    693:                void **ivaridx;
                    694: 
                    695:                if ((ivar = class_getInstanceVariable(((Object*)obj)->isa, name))) {
                    696:                       ivaridx = (void **)((char *)obj + ivar->ivar_offset);
                    697:                       *value = *ivaridx;
                    698:                } else
                    699:                       *value = 0;
                    700:        }
                    701:        return ivar;
                    702: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.