1 /* The implementation of class Object for Objective-C.
2 Copyright (C) 1993 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 GNU CC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* As a special exception, if you link this library with files compiled
21 with GCC to produce an executable, this does not cause the resulting
22 executable to be covered by the GNU General Public License. This
23 exception does not however invalidate any other reasons why the
24 executable file might be covered by the GNU General Public License. */
26 #include "objc/Object.h"
27 #include "objc/Protocol.h"
28 #include "objc/objc-api.h"
32 #define MAX_CLASS_NAME_LEN 256
34 @implementation Object
48 return [[self alloc] init];
53 return class_create_instance(self);
58 return object_dispose(self);
63 return [[self shallowCopy] deepen];
68 return object_copy(self);
83 return object_get_class(self);
88 return object_get_super_class(self);
91 - (MetaClass_t)metaClass
93 return object_get_meta_class(self);
98 return object_get_class_name(self);
108 return (unsigned int)self;
111 - (BOOL)isEqual:anObject
113 return self==anObject;
123 return object_is_class(self);
128 return object_is_instance(self);
131 - (BOOL)isKindOf:(Class_t)aClassObject
135 for (class = self->isa; class!=Nil; class = class_get_super_class(class))
136 if (class==aClassObject)
141 - (BOOL)isMemberOf:(Class_t)aClassObject
143 return self->isa==aClassObject;
146 - (BOOL)isKindOfClassNamed:(const char *)aClassName
150 if (aClassName!=NULL)
151 for (class = self->isa; class!=Nil; class = class_get_super_class(class))
152 if (!strcmp(class_get_class_name(class), aClassName))
157 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
159 return ((aClassName!=NULL)
160 &&!strcmp(class_get_class_name(self->isa), aClassName));
163 + (BOOL)instancesRespondTo:(SEL)aSel
165 return class_get_instance_method(self, aSel)!=METHOD_NULL;
168 - (BOOL)respondsTo:(SEL)aSel
170 return ((object_is_instance(self)
171 ?class_get_instance_method(self->isa, aSel)
172 :class_get_class_method(self->isa, aSel))!=METHOD_NULL);
175 + (IMP)instanceMethodFor:(SEL)aSel
177 return method_get_imp(class_get_instance_method(self, aSel));
180 // Indicates if the receiving class or instance conforms to the given protocol
181 // not usually overridden by subclasses
182 - (BOOL) conformsTo: (Protocol*)aProtocol
185 struct objc_protocol_list* proto_list;
187 for (proto_list = isa->protocols;
188 proto_list; proto_list = proto_list->next)
190 for (i=0; i < proto_list->count; i++)
192 if ([proto_list->list[i] conformsTo: aProtocol])
200 - (IMP)methodFor:(SEL)aSel
202 return (method_get_imp(object_is_instance(self)
203 ?class_get_instance_method(self->isa, aSel)
204 :class_get_class_method(self->isa, aSel)));
207 + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
209 return ((struct objc_method_description *)
210 class_get_instance_method(self, aSel));
213 - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
215 return ((struct objc_method_description *)
216 (object_is_instance(self)
217 ?class_get_instance_method(self->isa, aSel)
218 :class_get_class_method(self->isa, aSel)));
223 IMP msg = objc_msg_lookup(self, aSel);
225 return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
226 return (*msg)(self, aSel);
229 - perform:(SEL)aSel with:anObject
231 IMP msg = objc_msg_lookup(self, aSel);
233 return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
234 return (*msg)(self, aSel, anObject);
237 - perform:(SEL)aSel with:anObject1 with:anObject2
239 IMP msg = objc_msg_lookup(self, aSel);
241 return [self error:"invalid selector passed to %s", sel_get_name(_cmd)];
242 return (*msg)(self, aSel, anObject1, anObject2);
245 - forward:(SEL)aSel :(arglist_t)argFrame
247 return [self doesNotRecognize: aSel];
250 - performv:(SEL)aSel :(arglist_t)argFrame
252 return objc_msg_sendv(self, aSel, method_get_argsize(0), argFrame);
255 + poseAs:(Class_t)aClassObject
257 return class_pose_as(self, aClassObject);
260 - (Class_t)transmuteClassTo:(Class_t)aClassObject
262 if (object_is_instance(self))
263 if (class_is_class(aClassObject))
264 if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
265 if ([self isKindOf:aClassObject])
267 Class_t old_isa = isa;
274 - subclassResponsibility:(SEL)aSel
276 return [self error:"subclass should override %s", sel_get_name(aSel)];
279 - notImplemented:(SEL)aSel
281 return [self error:"method %s not implemented", sel_get_name(aSel)];
284 - doesNotRecognize:(SEL)aSel
286 return [self error:"%s does not recognize %s",
287 object_get_class_name(self), sel_get_name(aSel)];
290 - error:(const char *)aString, ...
292 #define FMT "error: %s (%s)\n%s\n"
293 char fmt[(strlen(FMT)+strlen(object_get_class_name(self))
294 +((aString!=NULL)?strlen(aString):0)+8)];
297 sprintf(fmt, FMT, object_get_class_name(self),
298 object_is_instance(self)?"instance":"class",
299 (aString!=NULL)?aString:"");
300 va_start(ap, aString);
301 (*_objc_error)(self, fmt, ap);
309 return class_get_version(self);
312 + setVersion:(int)aVersion
314 class_set_version(self, aVersion);
318 // These are used to write or read the instance variables
319 // declared in this particular part of the object. Subclasses
320 // should extend these, by calling [super read/write: aStream]
321 // before doing their own archiving. These methods are private, in
322 // the sense that they should only be called from subclasses.
324 - read: (TypedStream*)aStream
326 // [super read: aStream];
330 - write: (TypedStream*)aStream
332 // [super write: aStream];
336 - awake: (TypedStream*)aStream
338 // [super awake: aStream];