1/* The implementation of class Object for Objective-C. 2 Copyright (C) 1993, 1994, 1995, 1997, 2002, 2009 Free Software Foundation, Inc. 3 4This file is part of GCC. 5 6GCC is free software; you can redistribute it and/or modify it 7under the terms of the GNU General Public License as published by the 8Free Software Foundation; either version 3, or (at your option) any 9later version. 10 11GCC is distributed in the hope that it will be useful, but WITHOUT 12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14License for more details. 15 16Under Section 7 of GPL version 3, you are granted additional 17permissions described in the GCC Runtime Library Exception, version 183.1, as published by the Free Software Foundation. 19 20You should have received a copy of the GNU General Public License and 21a copy of the GCC Runtime Library Exception along with this program; 22see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23<http://www.gnu.org/licenses/>. */ 24 25#include <stdarg.h> 26#include <errno.h> 27#include "objc/Object.h" 28#include "objc/Protocol.h" 29#include "objc/objc-api.h" 30 31#define MAX_CLASS_NAME_LEN 256 32 33@implementation Object 34 35+ initialize 36{ 37 return self; 38} 39 40- init 41{ 42 return self; 43} 44 45+ new 46{ 47 return [[self alloc] init]; 48} 49 50+ alloc 51{ 52 return class_create_instance(self); 53} 54 55- free 56{ 57 return object_dispose(self); 58} 59 60- copy 61{ 62 return [[self shallowCopy] deepen]; 63} 64 65- shallowCopy 66{ 67 return object_copy(self); 68} 69 70- deepen 71{ 72 return self; 73} 74 75- deepCopy 76{ 77 return [self copy]; 78} 79 80- (Class)class 81{ 82 return object_get_class(self); 83} 84 85- (Class)superClass 86{ 87 return object_get_super_class(self); 88} 89 90- (MetaClass)metaClass 91{ 92 return object_get_meta_class(self); 93} 94 95- (const char *)name 96{ 97 return object_get_class_name(self); 98} 99 100- self 101{ 102 return self; 103} 104 105- (unsigned int)hash 106{ 107 return (size_t)self; 108} 109 110- (BOOL)isEqual:anObject 111{ 112 return self==anObject; 113} 114 115- (int)compare:(id)anotherObject; 116{ 117 if ([self isEqual:anotherObject]) 118 return 0; 119 // Ordering objects by their address is pretty useless, 120 // so subclasses should override this is some useful way. 121 else if ((id)self > anotherObject) 122 return 1; 123 else 124 return -1; 125} 126 127- (BOOL)isMetaClass 128{ 129 return NO; 130} 131 132- (BOOL)isClass 133{ 134 return object_is_class(self); 135} 136 137- (BOOL)isInstance 138{ 139 return object_is_instance(self); 140} 141 142- (BOOL)isKindOf:(Class)aClassObject 143{ 144 Class class; 145 146 for (class = self->isa; class!=Nil; class = class_get_super_class(class)) 147 if (class==aClassObject) 148 return YES; 149 return NO; 150} 151 152- (BOOL)isMemberOf:(Class)aClassObject 153{ 154 return self->isa==aClassObject; 155} 156 157- (BOOL)isKindOfClassNamed:(const char *)aClassName 158{ 159 Class class; 160 161 if (aClassName!=NULL) 162 for (class = self->isa; class!=Nil; class = class_get_super_class(class)) 163 if (!strcmp(class_get_class_name(class), aClassName)) 164 return YES; 165 return NO; 166} 167 168- (BOOL)isMemberOfClassNamed:(const char *)aClassName 169{ 170 return ((aClassName!=NULL) 171 &&!strcmp(class_get_class_name(self->isa), aClassName)); 172} 173 174+ (BOOL)instancesRespondTo:(SEL)aSel 175{ 176 return class_get_instance_method(self, aSel)!=METHOD_NULL; 177} 178 179- (BOOL)respondsTo:(SEL)aSel 180{ 181 return ((object_is_instance(self) 182 ?class_get_instance_method(self->isa, aSel) 183 :class_get_class_method(self->isa, aSel))!=METHOD_NULL); 184} 185 186+ (IMP)instanceMethodFor:(SEL)aSel 187{ 188 return method_get_imp(class_get_instance_method(self, aSel)); 189} 190 191// Indicates if the receiving class or instance conforms to the given protocol 192// not usually overridden by subclasses 193// 194// Modified 9/5/94 to always search the class object's protocol list, rather 195// than the meta class. 196 197+ (BOOL) conformsTo: (Protocol*)aProtocol 198{ 199 size_t i; 200 struct objc_protocol_list* proto_list; 201 id parent; 202 203 for (proto_list = ((Class)self)->protocols; 204 proto_list; proto_list = proto_list->next) 205 { 206 for (i=0; i < proto_list->count; i++) 207 { 208 if ([proto_list->list[i] conformsTo: aProtocol]) 209 return YES; 210 } 211 } 212 213 if ((parent = [self superClass])) 214 return [parent conformsTo: aProtocol]; 215 else 216 return NO; 217} 218 219- (BOOL) conformsTo: (Protocol*)aProtocol 220{ 221 return [[self class] conformsTo:aProtocol]; 222} 223 224- (IMP)methodFor:(SEL)aSel 225{ 226 return (method_get_imp(object_is_instance(self) 227 ?class_get_instance_method(self->isa, aSel) 228 :class_get_class_method(self->isa, aSel))); 229} 230 231+ (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel 232{ 233 return ((struct objc_method_description *) 234 class_get_instance_method(self, aSel)); 235} 236 237- (struct objc_method_description *)descriptionForMethod:(SEL)aSel 238{ 239 return ((struct objc_method_description *) 240 (object_is_instance(self) 241 ?class_get_instance_method(self->isa, aSel) 242 :class_get_class_method(self->isa, aSel))); 243} 244 245- perform:(SEL)aSel 246{ 247 IMP msg = objc_msg_lookup(self, aSel); 248 if (!msg) 249 return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; 250 return (*msg)(self, aSel); 251} 252 253- perform:(SEL)aSel with:anObject 254{ 255 IMP msg = objc_msg_lookup(self, aSel); 256 if (!msg) 257 return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; 258 return (*msg)(self, aSel, anObject); 259} 260 261- perform:(SEL)aSel with:anObject1 with:anObject2 262{ 263 IMP msg = objc_msg_lookup(self, aSel); 264 if (!msg) 265 return [self error:"invalid selector passed to %s", sel_get_name(_cmd)]; 266 return (*msg)(self, aSel, anObject1, anObject2); 267} 268 269- (retval_t)forward:(SEL)aSel :(arglist_t)argFrame 270{ 271 (void) argFrame; /* UNUSED */ 272 return (retval_t)[self doesNotRecognize: aSel]; 273} 274 275- (retval_t)performv:(SEL)aSel :(arglist_t)argFrame 276{ 277 return objc_msg_sendv(self, aSel, argFrame); 278} 279 280+ poseAs:(Class)aClassObject 281{ 282 return class_pose_as(self, aClassObject); 283} 284 285- (Class)transmuteClassTo:(Class)aClassObject 286{ 287 if (object_is_instance(self)) 288 if (class_is_class(aClassObject)) 289 if (class_get_instance_size(aClassObject)==class_get_instance_size(isa)) 290 if ([self isKindOf:aClassObject]) 291 { 292 Class old_isa = isa; 293 isa = aClassObject; 294 return old_isa; 295 } 296 return nil; 297} 298 299- subclassResponsibility:(SEL)aSel 300{ 301 return [self error:"subclass should override %s", sel_get_name(aSel)]; 302} 303 304- notImplemented:(SEL)aSel 305{ 306 return [self error:"method %s not implemented", sel_get_name(aSel)]; 307} 308 309- shouldNotImplement:(SEL)aSel 310{ 311 return [self error:"%s should not implement %s", 312 object_get_class_name(self), sel_get_name(aSel)]; 313} 314 315- doesNotRecognize:(SEL)aSel 316{ 317 return [self error:"%s does not recognize %s", 318 object_get_class_name(self), sel_get_name(aSel)]; 319} 320 321- error:(const char *)aString, ... 322{ 323#define FMT "error: %s (%s)\n%s\n" 324 char fmt[(strlen((char*)FMT)+strlen((char*)object_get_class_name(self)) 325 +((aString!=NULL)?strlen((char*)aString):0)+8)]; 326 va_list ap; 327 328 sprintf(fmt, FMT, object_get_class_name(self), 329 object_is_instance(self)?"instance":"class", 330 (aString!=NULL)?aString:""); 331 va_start(ap, aString); 332 objc_verror(self, OBJC_ERR_UNKNOWN, fmt, ap); 333 va_end(ap); 334 return nil; 335#undef FMT 336} 337 338+ (int)version 339{ 340 return class_get_version(self); 341} 342 343+ setVersion:(int)aVersion 344{ 345 class_set_version(self, aVersion); 346 return self; 347} 348 349+ (int)streamVersion: (TypedStream*)aStream 350{ 351 if (aStream->mode == OBJC_READONLY) 352 return objc_get_stream_class_version (aStream, self); 353 else 354 return class_get_version (self); 355} 356 357// These are used to write or read the instance variables 358// declared in this particular part of the object. Subclasses 359// should extend these, by calling [super read/write: aStream] 360// before doing their own archiving. These methods are private, in 361// the sense that they should only be called from subclasses. 362 363- read: (TypedStream*)aStream 364{ 365 (void) aStream; /* UNUSED */ 366 // [super read: aStream]; 367 return self; 368} 369 370- write: (TypedStream*)aStream 371{ 372 (void) aStream; /* UNUSED */ 373 // [super write: aStream]; 374 return self; 375} 376 377- awake 378{ 379 // [super awake]; 380 return self; 381} 382 383@end 384