blob: b9eb72afc01f3e3891ae6d62288ca22dacdbb610 [file] [log] [blame]
Ben Elliston88e17b51998-09-21 01:22:07 +00001/* The implementation of class Object for Objective-C.
Jakub Jelinek748086b2009-04-09 17:00:19 +02002 Copyright (C) 1993, 1994, 1995, 1997, 2002, 2009 Free Software Foundation, Inc.
Ben Elliston88e17b51998-09-21 01:22:07 +00003
Nathanael Nerode6c82ad22003-05-23 20:04:58 +00004This file is part of GCC.
Ben Elliston88e17b51998-09-21 01:22:07 +00005
Nathanael Nerode6c82ad22003-05-23 20:04:58 +00006GCC is free software; you can redistribute it and/or modify it
Ben Elliston88e17b51998-09-21 01:22:07 +00007under the terms of the GNU General Public License as published by the
Jakub Jelinek748086b2009-04-09 17:00:19 +02008Free Software Foundation; either version 3, or (at your option) any
Ben Elliston88e17b51998-09-21 01:22:07 +00009later version.
10
Nathanael Nerode6c82ad22003-05-23 20:04:58 +000011GCC is distributed in the hope that it will be useful, but WITHOUT
Ben Elliston88e17b51998-09-21 01:22:07 +000012ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14License for more details.
15
Jakub Jelinek748086b2009-04-09 17:00:19 +020016Under 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.
Ben Elliston88e17b51998-09-21 01:22:07 +000019
Jakub Jelinek748086b2009-04-09 17:00:19 +020020You 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/>. */
Ben Elliston88e17b51998-09-21 01:22:07 +000024
25#include <stdarg.h>
Kai Tietzb15b7ef2008-11-21 12:07:43 +000026#include <errno.h>
Ben Elliston88e17b51998-09-21 01:22:07 +000027#include "objc/Object.h"
28#include "objc/Protocol.h"
29#include "objc/objc-api.h"
30
Ben Elliston88e17b51998-09-21 01:22:07 +000031#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
Kai Tietzc24aadf2008-06-10 12:37:51 +0000115- (int)compare:(id)anotherObject;
Ben Elliston88e17b51998-09-21 01:22:07 +0000116{
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.
Kai Tietzb15b7ef2008-11-21 12:07:43 +0000121 else if ((id)self > anotherObject)
Ben Elliston88e17b51998-09-21 01:22:07 +0000122 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{
Kaveh R. Ghazi8f8c44c2002-06-15 17:50:14 +0000199 size_t i;
Ben Elliston88e17b51998-09-21 01:22:07 +0000200 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{
Kaveh R. Ghazib62cc132002-06-21 14:36:37 +0000271 (void) argFrame; /* UNUSED */
Ben Elliston88e17b51998-09-21 01:22:07 +0000272 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
Ben Elliston88e17b51998-09-21 01:22:07 +0000321- 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{
Kaveh R. Ghazib62cc132002-06-21 14:36:37 +0000365 (void) aStream; /* UNUSED */
Ben Elliston88e17b51998-09-21 01:22:07 +0000366 // [super read: aStream];
367 return self;
368}
369
370- write: (TypedStream*)aStream
371{
Kaveh R. Ghazib62cc132002-06-21 14:36:37 +0000372 (void) aStream; /* UNUSED */
Ben Elliston88e17b51998-09-21 01:22:07 +0000373 // [super write: aStream];
374 return self;
375}
376
377- awake
378{
379 // [super awake];
380 return self;
381}
382
383@end