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