~ubuntu-branches/ubuntu/trusty/gnustep-base/trusty

« back to all changes in this revision

Viewing changes to Source/NSObject.m

Tags: upstream-1.20.0
ImportĀ upstreamĀ versionĀ 1.20.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/** Implementation of NSObject for GNUStep
2
 
   Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
 
2
   Copyright (C) 1994-2010 Free Software Foundation, Inc.
3
3
 
4
4
   Written by:  Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
5
5
   Date: August 1994
22
22
   Boston, MA 02111 USA.
23
23
 
24
24
   <title>NSObject class reference</title>
25
 
   $Date: 2008-11-26 09:20:34 +0000 (Wed, 26 Nov 2008) $ $Revision: 27135 $
 
25
   $Date: 2010-04-26 15:32:22 -0600 (Mon, 26 Apr 2010) $ $Revision: 30239 $
26
26
   */
27
27
 
28
28
/* On some versions of mingw we need to work around bad function declarations
33
33
#define InterlockedDecrement    BadInterlockedDecrement
34
34
#endif
35
35
 
36
 
#include "config.h"
37
 
#include "GNUstepBase/preface.h"
38
 
#include <stdarg.h>
39
 
#include "Foundation/NSObject.h"
 
36
#import "common.h"
40
37
#include <objc/Protocol.h>
41
 
#include "Foundation/NSMethodSignature.h"
42
 
#include "Foundation/NSInvocation.h"
43
 
#include "Foundation/NSLock.h"
44
 
#include "Foundation/NSAutoreleasePool.h"
45
 
#include "Foundation/NSString.h"
46
 
#include "Foundation/NSArray.h"
47
 
#include "Foundation/NSException.h"
48
 
#include "Foundation/NSPortCoder.h"
49
 
#include "Foundation/NSDistantObject.h"
50
 
#include "Foundation/NSZone.h"
51
 
#include "Foundation/NSDebug.h"
52
 
#include "Foundation/NSThread.h"
53
 
#include "Foundation/NSNotification.h"
54
 
#include "Foundation/NSObjCRuntime.h"
55
 
#include "Foundation/NSMapTable.h"
56
 
#include <limits.h>
57
 
#include "GNUstepBase/GSLocale.h"
 
38
#import "Foundation/NSMethodSignature.h"
 
39
#import "Foundation/NSInvocation.h"
 
40
#import "Foundation/NSLock.h"
 
41
#import "Foundation/NSAutoreleasePool.h"
 
42
#import "Foundation/NSArray.h"
 
43
#import "Foundation/NSException.h"
 
44
#import "Foundation/NSPortCoder.h"
 
45
#import "Foundation/NSDistantObject.h"
 
46
#import "Foundation/NSThread.h"
 
47
#import "Foundation/NSNotification.h"
 
48
#import "Foundation/NSMapTable.h"
 
49
#import "GNUstepBase/GSLocale.h"
58
50
#ifdef HAVE_LOCALE_H
59
51
#include <locale.h>
60
52
#endif
65
57
#ifdef  HAVE_SYS_SIGNAL_H
66
58
#include        <sys/signal.h>
67
59
#endif
 
60
#ifdef __FreeBSD__
 
61
#include <fenv.h>
 
62
#endif
68
63
 
69
 
#include "GSPrivate.h"
 
64
#import "GSPrivate.h"
70
65
 
71
66
 
72
67
#ifndef NeXT_RUNTIME
92
87
#include        <gc.h>
93
88
#include        <gc_typed.h>
94
89
 
 
90
static SEL finalize_sel;
 
91
static IMP finalize_imp;
95
92
#endif
96
93
 
97
94
static Class    NSConstantStringClass;
109
106
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector;
110
107
@end
111
108
 
 
109
@interface GSContentAccessingProxy : NSProxy 
 
110
{
 
111
  NSObject<NSDiscardableContent> *object;
 
112
}
 
113
- (id) initWithObject: (id)anObject;
 
114
@end
 
115
 
112
116
/*
113
117
 * allocationLock is needed when running multi-threaded for 
114
 
 * protecting the map table of zombie information and for retain
115
 
 * count protection (when using a map table ... REFCNT_LOCAL is NO)
 
118
 * protecting the map table of zombie information.
116
119
 */
117
 
static objc_mutex_t allocationLock = NULL;
 
120
static NSLock *allocationLock;
118
121
 
119
122
BOOL    NSZombieEnabled = NO;
120
123
BOOL    NSDeallocateZombies = NO;
121
124
 
122
125
@class  NSZombie;
123
126
static Class            zombieClass;
124
 
static NSMapTable       zombieMap;
 
127
static NSMapTable       *zombieMap;
125
128
 
 
129
#if     !GS_WITH_GC
126
130
static void GSMakeZombie(NSObject *o)
127
131
{
128
132
  Class c = ((id)o)->class_pointer;
130
134
  ((id)o)->class_pointer = zombieClass;
131
135
  if (NSDeallocateZombies == NO)
132
136
    {
133
 
      if (allocationLock != 0)
134
 
        {
135
 
          objc_mutex_lock(allocationLock);
136
 
        }
 
137
      [allocationLock lock];
137
138
      NSMapInsert(zombieMap, (void*)o, (void*)c);
138
 
      if (allocationLock != 0)
139
 
        {
140
 
          objc_mutex_unlock(allocationLock);
141
 
        }
 
139
      [allocationLock unlock];
142
140
    }
143
141
}
 
142
#endif
144
143
 
145
144
static void GSLogZombie(id o, SEL sel)
146
145
{
148
147
 
149
148
  if (NSDeallocateZombies == NO)
150
149
    {
151
 
      if (allocationLock != 0)
152
 
        {
153
 
          objc_mutex_lock(allocationLock);
154
 
        }
 
150
      [allocationLock lock];
155
151
      c = NSMapGet(zombieMap, (void*)o);
156
 
      if (allocationLock != 0)
157
 
        {
158
 
          objc_mutex_unlock(allocationLock);
159
 
        }
 
152
      [allocationLock unlock];
160
153
    }
161
154
  if (c == 0)
162
155
    {
163
 
      NSLog(@"Deallocated object (0x%x) sent %@",
 
156
      NSLog(@"Deallocated object (%p) sent %@",
164
157
        o, NSStringFromSelector(sel));
165
158
    }
166
159
  else
167
160
    {
168
 
      NSLog(@"Deallocated %@ (0x%x) sent %@",
169
 
        NSStringFromClass(c), o, NSStringFromSelector(sel));
 
161
      NSLog(@"Deallocated %@ (%p) sent %@",
 
162
        c, o, NSStringFromSelector(sel));
170
163
    }
171
164
  if (GSPrivateEnvironmentFlag("CRASH_ON_ZOMBIE", NO) == YES)
172
165
    {
177
170
 
178
171
/*
179
172
 *      Reference count and memory management
180
 
 *
181
 
 *      If REFCNT_LOCAL is defined, reference counts for object are stored
182
 
 *      with the object, otherwise they are stored in a global map table
183
 
 *      that has to be protected by mutexes in a multithreraded environment.
184
 
 *      You therefore want REFCNT_LOCAL defined for best performance.
185
 
 *
186
 
 *      If CACHE_ZONE is defined, the zone in which an object has been
187
 
 *      allocated is stored with the object - this makes lookup of the
188
 
 *      correct zone to free memory very fast.
 
173
 *      Reference counts for object are stored
 
174
 *      with the object.
 
175
 *      The zone in which an object has been
 
176
 *      allocated is stored with the object.
189
177
 */
190
178
 
191
 
 
192
 
#if     GS_WITH_GC == 0 && !defined(NeXT_RUNTIME)
193
 
#define REFCNT_LOCAL    1
194
 
#define CACHE_ZONE      1
195
 
#endif
196
 
 
197
 
 
198
179
/* Now, if we are on a platform where we know how to do atomic
199
180
 * read, increment, and decrement, then we define the GSATOMICREAD
200
181
 * macro and macros or functions to increment/decrement.
209
190
#undef  GSATOMICREAD
210
191
#endif
211
192
 
212
 
#if     defined(REFCNT_LOCAL)
213
 
 
214
 
#if     defined(__MINGW32__)
 
193
#if     defined(__MINGW__)
215
194
#ifndef _WIN64
216
195
#undef InterlockedIncrement
217
196
#undef InterlockedDecrement
229
208
#define GSAtomicIncrement(X)    InterlockedIncrement((LONG volatile*)X)
230
209
#define GSAtomicDecrement(X)    InterlockedDecrement((LONG volatile*)X)
231
210
 
232
 
#endif
 
211
 
 
212
#elif defined(__llvm__) || (defined(USE_ATOMIC_BUILDINS) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)))
 
213
/* Use the GCC atomic operations with recent GCC versions */
 
214
 
 
215
typedef int32_t volatile *gsatomic_t;
 
216
#define GSATOMICREAD(X) (*(X))
 
217
#define GSAtomicIncrement(X)    __sync_fetch_and_add(X, 1)
 
218
#define GSAtomicDecrement(X)    __sync_fetch_and_sub(X, 1)
233
219
 
234
220
 
235
221
#elif   defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
258
244
 return *X;
259
245
}
260
246
 
261
 
#elif defined(__PPC__)
 
247
#elif defined(__PPC__) || defined(__POWERPC__)
262
248
 
263
249
typedef int32_t volatile *gsatomic_t;
264
250
 
269
255
{
270
256
  int tmp;
271
257
  __asm__ __volatile__ (
272
 
    "modified:"
 
258
    "0:"
273
259
    "lwarx %0,0,%1 \n"
274
260
    "addic %0,%0,1 \n"
275
261
    "stwcx. %0,0,%1 \n"
276
 
    "bne- modified \n"
 
262
    "bne- 0b \n"
277
263
    :"=&r" (tmp)
278
264
    :"r" (X)
279
265
    :"cc", "memory");
285
271
{
286
272
  int tmp;
287
273
  __asm__ __volatile__ (
288
 
    "modified:"
 
274
    "0:"
289
275
    "lwarx %0,0,%1 \n"
290
276
    "addic %0,%0,-1 \n"
291
277
    "stwcx. %0,0,%1 \n"
292
 
    "bne- modified \n"
 
278
    "bne- 0b \n"
293
279
    :"=&r" (tmp)
294
280
    :"r" (X)
295
281
    :"cc", "memory");
296
282
  return *X;
297
283
}
298
284
 
 
285
#elif defined(__m68k__)
 
286
 
 
287
typedef int32_t volatile *gsatomic_t;
 
288
 
 
289
#define GSATOMICREAD(X) (*(X))
 
290
 
 
291
static __inline__ int
 
292
GSAtomicIncrement(gsatomic_t X)
 
293
{
 
294
  __asm__ __volatile__ (
 
295
    "addq%.l %#1, %0"
 
296
    :"=m" (*X));
 
297
    return *X;
 
298
}
 
299
 
 
300
static __inline__ int
 
301
GSAtomicDecrement(gsatomic_t X)
 
302
{
 
303
  __asm__ __volatile__ (
 
304
    "subq%.l %#1, %0"
 
305
    :"=m" (*X));
 
306
    return *X;
 
307
}
 
308
 
 
309
#elif defined(__mips__)
 
310
 
 
311
typedef int32_t volatile *gsatomic_t;
 
312
 
 
313
#define GSATOMICREAD(X) (*(X))
 
314
 
 
315
static __inline__ int
 
316
GSAtomicIncrement(gsatomic_t X)
 
317
{
 
318
  int tmp;
 
319
 
 
320
  __asm__ __volatile__ (
 
321
    "   .set  mips2  \n"
 
322
    "0: ll    %0, %1 \n"
 
323
    "   addiu %0, 1  \n"
 
324
    "   sc    %0, %1 \n"
 
325
    "   beqz  %0, 0b  \n"
 
326
    :"=&r" (tmp), "=m" (*X));
 
327
    return *X;
 
328
}
 
329
 
 
330
static __inline__ int
 
331
GSAtomicDecrement(gsatomic_t X)
 
332
{
 
333
  int tmp;
 
334
 
 
335
  __asm__ __volatile__ (
 
336
    "   .set  mips2  \n"
 
337
    "0: ll    %0, %1 \n"
 
338
    "   addiu %0, -1 \n"
 
339
    "   sc    %0, %1 \n"
 
340
    "   beqz  %0, 0b  \n"
 
341
    :"=&r" (tmp), "=m" (*X));
 
342
    return *X;
 
343
}
299
344
#endif
300
345
 
301
 
#if     defined(REFCNT_LOCAL) && !defined(GSATOMICREAD)
 
346
#if     !defined(GSATOMICREAD)
302
347
 
303
348
/*
304
349
 * Having just one allocationLock for all leads to lock contention
305
350
 * if there are lots of threads doing lots of retain/release calls.
306
 
 * To alleviate this, if using REFCNT_LOCAL, instead of a single
 
351
 * To alleviate this, instead of a single
307
352
 * allocationLock for all objects, we divide the object space into
308
353
 * chunks, each with its own lock. The chunk is selected by shifting
309
354
 * off the low-order ALIGNBITS of the object's pointer (these bits
316
361
#define LOCKMASK (LOCKCOUNT-1)
317
362
#define ALIGNBITS 3
318
363
 
319
 
static objc_mutex_t allocationLocks[LOCKCOUNT] = { 0 };
 
364
static NSLock *allocationLocks[LOCKCOUNT] = { 0 };
320
365
 
321
 
static inline objc_mutex_t GSAllocationLockForObject(id p)
 
366
static inline NSLock *GSAllocationLockForObject(id p)
322
367
{
323
 
  unsigned i = ((((unsigned)(uintptr_t)p) >> ALIGNBITS) & LOCKMASK);
 
368
  NSUInteger i = ((((NSUInteger)(uintptr_t)p) >> ALIGNBITS) & LOCKMASK);
324
369
  return allocationLocks[i];
325
370
}
326
371
 
332
377
#endif
333
378
#define ALIGN __alignof__(double)
334
379
 
335
 
#if     defined(REFCNT_LOCAL) || defined(CACHE_ZONE)
336
 
 
337
380
/*
338
381
 *      Define a structure to hold information that is held locally
339
382
 *      (before the start) in each object.
340
383
 */
341
384
typedef struct obj_layout_unpadded {
342
 
#if     defined(REFCNT_LOCAL)
343
 
    unsigned    retained;
344
 
#endif
345
 
#if     defined(CACHE_ZONE)
 
385
    NSUInteger  retained;
346
386
    NSZone      *zone;
347
 
#endif
348
387
} unp;
349
388
#define UNP sizeof(unp)
350
389
 
354
393
 *      structure correct.
355
394
 */
356
395
struct obj_layout {
357
 
#if     defined(REFCNT_LOCAL)
358
 
    unsigned    retained;
359
 
#endif
360
 
#if     defined(CACHE_ZONE)
 
396
    NSUInteger  retained;
361
397
    NSZone      *zone;
362
 
#endif
363
398
    char        padding[ALIGN - ((UNP % ALIGN) ? (UNP % ALIGN) : ALIGN)];
364
399
};
365
400
typedef struct obj_layout *obj;
366
401
 
367
 
#endif  /* defined(REFCNT_LOCAL) || defined(CACHE_ZONE) */
368
 
 
369
 
#if !defined(REFCNT_LOCAL)
370
 
 
371
 
/*
372
 
 * Set up map table for non-local reference counts.
373
 
 */
374
 
 
375
 
#define GSI_MAP_EQUAL(M, X, Y)  (X.obj == Y.obj)
376
 
#define GSI_MAP_HASH(M, X)      (X.uint >> 2)
377
 
#define GSI_MAP_RETAIN_KEY(M, X)
378
 
#define GSI_MAP_RELEASE_KEY(M, X)
379
 
#define GSI_MAP_RETAIN_VAL(M, X)
380
 
#define GSI_MAP_RELEASE_VAL(M, X)
381
 
#define GSI_MAP_KTYPES  GSUNION_OBJ|GSUNION_INT
382
 
#define GSI_MAP_VTYPES  GSUNION_INT
383
 
#define GSI_MAP_NOCLEAN 1
384
 
 
385
 
#include "GNUstepBase/GSIMap.h"
386
 
 
387
 
static GSIMapTable_t    retain_counts = {0};
388
 
 
389
 
#endif  /* !defined(REFCNT_LOCAL) */
390
 
 
391
402
 
392
403
/**
393
404
 * Examines the extra reference count for the object and, if non-zero
402
413
#if     !GS_WITH_GC
403
414
  if (double_release_check_enabled)
404
415
    {
405
 
      unsigned release_count;
406
 
      unsigned retain_count = [anObject retainCount];
 
416
      NSUInteger release_count;
 
417
      NSUInteger retain_count = [anObject retainCount];
407
418
      release_count = [autorelease_class autoreleaseCountForObject: anObject];
408
419
      if (release_count >= retain_count)
409
420
        [NSException raise: NSGenericException
410
421
                    format: @"Release would release object too many times."];
411
422
    }
412
 
#if     defined(REFCNT_LOCAL)
413
423
  if (allocationLock != 0)
414
424
    {
415
425
#if     defined(GSATOMICREAD)
434
444
          return YES;
435
445
        }
436
446
#else   /* GSATOMICREAD */
437
 
      objc_mutex_t theLock = GSAllocationLockForObject(anObject);
 
447
      NSLock *theLock = GSAllocationLockForObject(anObject);
438
448
 
439
 
      objc_mutex_lock(theLock);
 
449
      [theLock lock];
440
450
      if (((obj)anObject)[-1].retained == 0)
441
451
        {
442
 
          objc_mutex_unlock(theLock);
 
452
          [theLock unlock];
443
453
          return YES;
444
454
        }
445
455
      else
446
456
        {
447
457
          ((obj)anObject)[-1].retained--;
448
 
          objc_mutex_unlock(theLock);
 
458
          [theLock unlock];
449
459
          return NO;
450
460
        }
451
461
#endif  /* GSATOMICREAD */
462
472
          return NO;
463
473
        }
464
474
    }
465
 
#else
466
 
  GSIMapNode    node;
467
 
 
468
 
  if (allocationLock != 0)
469
 
    {
470
 
      objc_mutex_lock(allocationLock);
471
 
      node = GSIMapNodeForKey(&retain_counts, (GSIMapKey)anObject);
472
 
      if (node == 0)
473
 
        {
474
 
          objc_mutex_unlock(allocationLock);
475
 
          return YES;
476
 
        }
477
 
      if (node->value.uint == 0)
478
 
        {
479
 
          GSIMapRemoveKey((GSIMapTable)&retain_counts, (GSIMapKey)anObject);
480
 
          objc_mutex_unlock(allocationLock);
481
 
          return YES;
482
 
        }
483
 
      else
484
 
        {
485
 
          (node->value.uint)--;
486
 
        }
487
 
      objc_mutex_unlock(allocationLock);
488
 
    }
489
 
  else
490
 
    {
491
 
      node = GSIMapNodeForKey(&retain_counts, (GSIMapKey)anObject);
492
 
      if (node == 0)
493
 
        {
494
 
          return YES;
495
 
        }
496
 
      if ((node->value.uint) == 0)
497
 
        {
498
 
          GSIMapRemoveKey((GSIMapTable)&retain_counts, (GSIMapKey)anObject);
499
 
          return YES;
500
 
        }
501
 
      else
502
 
        {
503
 
          --(node->value.uint);
504
 
        }
505
 
    }
506
 
#endif
507
 
#endif
 
475
#endif /* !GS_WITH_GC */
508
476
  return NO;
509
477
}
510
478
 
513
481
 * from 0 to the maximum unsigned integer value minus one).<br />
514
482
 * The retain count for an object is this value plus one.
515
483
 */
516
 
inline unsigned
 
484
inline NSUInteger
517
485
NSExtraRefCount(id anObject)
518
486
{
519
487
#if     GS_WITH_GC
520
488
  return UINT_MAX - 1;
521
489
#else   /* GS_WITH_GC */
522
 
#if     defined(REFCNT_LOCAL)
523
490
  return ((obj)anObject)[-1].retained;
524
 
#else
525
 
  GSIMapNode    node;
526
 
  unsigned      ret;
527
 
 
528
 
  if (allocationLock != 0)
529
 
    {
530
 
      objc_mutex_t theLock = GSAllocationLockForObject(anObject);
531
 
 
532
 
      objc_mutex_lock(theLock);
533
 
      node = GSIMapNodeForKey(&retain_counts, (GSIMapKey)anObject);
534
 
      if (node == 0)
535
 
        {
536
 
          ret = 0;
537
 
        }
538
 
      else
539
 
        {
540
 
          ret = node->value.uint;
541
 
        }
542
 
      objc_mutex_unlock(theLock);
543
 
    }
544
 
  else
545
 
    {
546
 
      node = GSIMapNodeForKey(&retain_counts, (GSIMapKey)anObject);
547
 
      if (node == 0)
548
 
        {
549
 
          ret = 0;
550
 
        }
551
 
      else
552
 
        {
553
 
          ret = node->value.uint;
554
 
        }
555
 
    }
556
 
  return ret;
557
 
#endif
558
 
#endif
 
491
#endif /* GS_WITH_GC */
559
492
}
560
493
 
561
494
/**
570
503
#if     GS_WITH_GC
571
504
  return;
572
505
#else   /* GS_WITH_GC */
573
 
#if     defined(REFCNT_LOCAL)
574
506
  if (allocationLock != 0)
575
507
    {
576
508
#if     defined(GSATOMICREAD)
585
517
            format: @"NSIncrementExtraRefCount() asked to increment too far"];
586
518
        }
587
519
#else   /* GSATOMICREAD */
588
 
      objc_mutex_t theLock = GSAllocationLockForObject(anObject);
 
520
      NSLock *theLock = GSAllocationLockForObject(anObject);
589
521
 
590
 
      objc_mutex_lock(theLock);
 
522
      [theLock lock];
591
523
      if (((obj)anObject)[-1].retained == UINT_MAX - 1)
592
524
        {
593
 
          objc_mutex_unlock (theLock);
 
525
          [theLock unlock];
594
526
          [NSException raise: NSInternalInconsistencyException
595
527
            format: @"NSIncrementExtraRefCount() asked to increment too far"];
596
528
        }
597
529
      ((obj)anObject)[-1].retained++;
598
 
      objc_mutex_unlock (theLock);
 
530
      [theLock unlock];
599
531
#endif  /* GSATOMICREAD */
600
532
    }
601
533
  else
607
539
        }
608
540
      ((obj)anObject)[-1].retained++;
609
541
    }
610
 
#else   /* REFCNT_LOCAL */
611
 
  GSIMapNode    node;
612
 
 
613
 
  if (allocationLock != 0)
614
 
    {
615
 
      objc_mutex_lock(allocationLock);
616
 
      node = GSIMapNodeForKey(&retain_counts, (GSIMapKey)anObject);
617
 
      if (node != 0)
618
 
        {
619
 
          if ((node->value.uint) == UINT_MAX - 1)
620
 
            {
621
 
              objc_mutex_unlock(allocationLock);
622
 
              [NSException raise: NSInternalInconsistencyException
623
 
                format:
624
 
                @"NSIncrementExtraRefCount() asked to increment too far"];
625
 
            }
626
 
          (node->value.uint)++;
627
 
        }
628
 
      else
629
 
        {
630
 
          GSIMapAddPair(&retain_counts, (GSIMapKey)anObject, (GSIMapVal)1);
631
 
        }
632
 
      objc_mutex_unlock(allocationLock);
633
 
    }
634
 
  else
635
 
    {
636
 
      node = GSIMapNodeForKey(&retain_counts, (GSIMapKey)anObject);
637
 
      if (node != 0)
638
 
        {
639
 
          if ((node->value.uint) == UINT_MAX - 1)
640
 
            {
641
 
              [NSException raise: NSInternalInconsistencyException
642
 
                format:
643
 
                @"NSIncrementExtraRefCount() asked to increment too far"];
644
 
            }
645
 
          (node->value.uint)++;
646
 
        }
647
 
      else
648
 
        {
649
 
          GSIMapAddPair(&retain_counts, (GSIMapKey)anObject, (GSIMapVal)1);
650
 
        }
651
 
    }
652
 
#endif  /* REFCNT_LOCAL */
653
542
#endif  /* GS_WITH_GC */
654
543
}
655
544
 
 
545
#ifndef NDEBUG
 
546
#define AADD(c, o) GSDebugAllocationAdd(c, o)
 
547
#define AREM(c, o) GSDebugAllocationRemove(c, o)
 
548
#else
 
549
#define AADD(c, o) 
 
550
#define AREM(c, o) 
 
551
#endif
656
552
 
657
553
/*
658
554
 *      Now do conditional compilation of memory allocation functions
664
560
inline NSZone *
665
561
GSObjCZone(NSObject *object)
666
562
{
667
 
  return 0;
 
563
  GSOnceFLog(@"GSObjCZone() is deprecated ... use -zone instead");
 
564
  /* MacOS-X 10.5 seems to return the default malloc zone if GC is enabled.
 
565
   */
 
566
  return NSDefaultMallocZone();
668
567
}
669
568
 
670
569
static void
671
570
GSFinalize(void* object, void* data)
672
571
{
673
 
  [(id)object gcFinalize];
674
 
#ifndef NDEBUG
675
 
  GSDebugAllocationRemove(((id)object)->class_pointer, (id)object);
676
 
#endif
 
572
  [(id)object finalize];
 
573
  AREM(((id)object)->class_pointer, (id)object);
677
574
  ((id)object)->class_pointer = (void*)0xdeadface;
678
575
}
679
576
 
680
 
inline NSObject *
681
 
NSAllocateObject(Class aClass, unsigned extraBytes, NSZone *zone)
 
577
static BOOL
 
578
GSIsFinalizable(Class c)
 
579
{
 
580
  if (get_imp(c, finalize_sel) != finalize_imp)
 
581
    return YES;
 
582
  return NO;
 
583
}
 
584
 
 
585
inline id
 
586
NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone)
682
587
{
683
588
  id    new;
684
589
  int   size;
 
590
  GC_descr      gc_type;
685
591
 
686
592
  NSCAssert((CLS_ISCLASS(aClass)), @"Bad class for new object");
687
 
  size = aClass->instance_size + extraBytes;
688
 
  if (zone == GSAtomicMallocZone())
689
 
    {
690
 
      new = NSZoneMalloc(zone, size);
 
593
  gc_type = (GC_descr)aClass->gc_object_type;
 
594
  size = class_getInstanceSize(aClass) + extraBytes;
 
595
  if (size % sizeof(void*) != 0)
 
596
    {
 
597
      /* Size must be a multiple of pointer size for the garbage collector
 
598
       * to be able to allocate explicitly typed memory.
 
599
       */
 
600
      size += sizeof(void*) - size % sizeof(void*);
 
601
    }
 
602
 
 
603
  if (gc_type == 0)
 
604
    {
 
605
      new = NSZoneCalloc(zone, 1, size);
 
606
      NSLog(@"No garbage collection information for '%s'",
 
607
        class_getName(aClass));
691
608
    }
692
609
  else
693
610
    {
694
 
      GC_descr  gc_type = (GC_descr)aClass->gc_object_type;
695
 
 
696
 
      if (gc_type == 0)
697
 
        {
698
 
          new = NSZoneMalloc(zone, size);
699
 
          NSLog(@"No garbage collection information for '%s'",
700
 
            GSNameFromClass(aClass));
701
 
        }
702
 
      else if ([aClass requiresTypedMemory])
703
 
        {
704
 
          new = GC_CALLOC_EXPLICTLY_TYPED(1, size, gc_type);
705
 
        }
706
 
      else
707
 
        {
708
 
          new = NSZoneMalloc(zone, size);
709
 
        }
 
611
      new = GC_calloc_explicitly_typed(1, size, gc_type);
710
612
    }
711
613
 
712
614
  if (new != nil)
713
615
    {
714
 
      memset(new, 0, size);
715
616
      new->class_pointer = aClass;
716
 
      if (__objc_responds_to(new, @selector(gcFinalize)))
 
617
      if (GSIsFinalizable(aClass))
717
618
        {
718
 
#ifndef NDEBUG
719
 
          /*
720
 
           *    We only do allocation counting for objects that can be
721
 
           *    finalised - for other objects we have no way of decrementing
722
 
           *    the count when the object is collected.
 
619
          /* We only do allocation counting for objects that can be
 
620
           * finalised - for other objects we have no way of decrementing
 
621
           * the count when the object is collected.
723
622
           */
724
 
          GSDebugAllocationAdd(aClass, new);
725
 
#endif
 
623
          AADD(aClass, new);
726
624
          GC_REGISTER_FINALIZER (new, GSFinalize, NULL, NULL, NULL);
727
625
        }
728
626
    }
730
628
}
731
629
 
732
630
inline void
733
 
NSDeallocateObject(NSObject *anObject)
 
631
NSDeallocateObject(id anObject)
734
632
{
735
633
}
736
634
 
737
635
#else   /* GS_WITH_GC */
738
636
 
739
 
#if     defined(REFCNT_LOCAL) || defined(CACHE_ZONE)
740
 
 
741
 
#if defined(CACHE_ZONE)
742
 
 
743
637
inline NSZone *
744
638
GSObjCZone(NSObject *object)
745
639
{
746
 
  if (GSObjCClass(object) == NSConstantStringClass)
 
640
  GSOnceFLog(@"GSObjCZone() is deprecated ... use -zone instead");
 
641
  if (object_getClass(object) == NSConstantStringClass)
747
642
    return NSDefaultMallocZone();
748
643
  return ((obj)object)[-1].zone;
749
644
}
750
645
 
751
 
#else   /* defined(CACHE_ZONE)  */
752
 
 
753
 
inline NSZone *
754
 
GSObjCZone(NSObject *object)
755
 
{
756
 
  if (GSObjCClass(object) == NSConstantStringClass)
757
 
    return NSDefaultMallocZone();
758
 
  return NSZoneFromPointer(&((obj)object)[-1]);
759
 
}
760
 
 
761
 
#endif  /* defined(CACHE_ZONE)  */
762
 
 
763
 
inline NSObject *
764
 
NSAllocateObject (Class aClass, unsigned extraBytes, NSZone *zone)
765
 
{
766
 
#ifndef NDEBUG
767
 
  extern void GSDebugAllocationAdd(Class c, id o);
768
 
#endif
 
646
inline id
 
647
NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone)
 
648
{
769
649
  id    new;
770
650
  int   size;
771
651
 
772
652
  NSCAssert((CLS_ISCLASS(aClass)), @"Bad class for new object");
773
 
  size = aClass->instance_size + extraBytes + sizeof(struct obj_layout);
 
653
  size = class_getInstanceSize(aClass) + extraBytes + sizeof(struct obj_layout);
774
654
  if (zone == 0)
775
655
    {
776
656
      zone = NSDefaultMallocZone();
779
659
  if (new != nil)
780
660
    {
781
661
      memset (new, 0, size);
782
 
#if     defined(CACHE_ZONE)
783
662
      ((obj)new)->zone = zone;
784
 
#endif
785
663
      new = (id)&((obj)new)[1];
786
664
      new->class_pointer = aClass;
787
 
#ifndef NDEBUG
788
 
      GSDebugAllocationAdd(aClass, new);
789
 
#endif
 
665
      AADD(aClass, new);
790
666
    }
791
667
  return new;
792
668
}
793
669
 
794
670
inline void
795
 
NSDeallocateObject(NSObject *anObject)
 
671
NSDeallocateObject(id anObject)
796
672
{
797
 
#ifndef NDEBUG
798
 
  extern void GSDebugAllocationRemove(Class c, id o);
799
 
#endif
800
673
  if ((anObject!=nil) && CLS_ISCLASS(((id)anObject)->class_pointer))
801
674
    {
802
675
      obj       o = &((obj)anObject)[-1];
803
 
      NSZone    *z = GSObjCZone(anObject);
 
676
      NSZone    *z = o->zone;
804
677
 
805
 
#ifndef NDEBUG
806
 
      GSDebugAllocationRemove(((id)anObject)->class_pointer, (id)anObject);
807
 
#endif
 
678
      AREM(((id)anObject)->class_pointer, (id)anObject);
808
679
      if (NSZombieEnabled == YES)
809
680
        {
810
681
          GSMakeZombie(anObject);
822
693
  return;
823
694
}
824
695
 
 
696
#endif  /* GS_WITH_GC */
 
697
 
 
698
 
 
699
void
 
700
GSPrivateSwizzle(id o, Class c)
 
701
{
 
702
  if ((Class)o->class_pointer != c)
 
703
    {
 
704
#if     GS_WITH_GC
 
705
      /* We only do allocation counting for objects that can be
 
706
       * finalised - for other objects we have no way of decrementing
 
707
       * the count when the object is collected.
 
708
       */
 
709
      if (GSIsFinalizable(o->class_pointer))
 
710
        {
 
711
          /* Already finalizable, so we just need to do any allocation
 
712
           * accounting.
 
713
           */
 
714
          AREM(o->class_pointer, o);
 
715
          AADD(c, o);
 
716
        }
 
717
      else if (GSIsFinalizable(c))
 
718
        {
 
719
          /* New class is finalizable, so we must register the instance
 
720
           * for finalisation and do allocation acounting for it.
 
721
           */
 
722
          AADD(c, o);
 
723
          GC_REGISTER_FINALIZER (o, GSFinalize, NULL, NULL, NULL);
 
724
        }
825
725
#else
826
 
 
827
 
inline NSZone *
828
 
GSObjCZone(NSObject *object)
829
 
{
830
 
  if (GSObjCClass(object) == NSConstantStringClass)
831
 
    return NSDefaultMallocZone();
832
 
  return NSZoneFromPointer(object);
833
 
}
834
 
 
835
 
inline NSObject *
836
 
NSAllocateObject (Class aClass, unsigned extraBytes, NSZone *zone)
837
 
{
838
 
  id    new;
839
 
  int   size;
840
 
 
841
 
  NSCAssert((CLS_ISCLASS(aClass)), @"Bad class for new object");
842
 
  size = aClass->instance_size + extraBytes;
843
 
  new = NSZoneMalloc (zone, size);
844
 
  if (new != nil)
845
 
    {
846
 
      memset (new, 0, size);
847
 
      new->class_pointer = aClass;
848
 
#ifndef NDEBUG
849
 
      GSDebugAllocationAdd(aClass, new);
850
 
#endif
851
 
    }
852
 
  return new;
853
 
}
854
 
 
855
 
inline void
856
 
NSDeallocateObject(NSObject *anObject)
857
 
{
858
 
  if ((anObject!=nil) && CLS_ISCLASS(((id)anObject)->class_pointer))
859
 
    {
860
 
      NSZone    *z = [anObject zone];
861
 
 
862
 
#ifndef NDEBUG
863
 
      GSDebugAllocationRemove(((id)anObject)->class_pointer, (id)anObject);
864
 
#endif
865
 
      if (NSZombieEnabled == YES)
866
 
        {
867
 
          GSMakeZombie(anObject);
868
 
          if (NSDeallocateZombies == YES)
869
 
            {
870
 
              NSZoneFree(z, anObject);
871
 
            }
872
 
        }
873
 
      else
874
 
        {
875
 
          ((id)anObject)->class_pointer = (void*) 0xdeadface;
876
 
          NSZoneFree(z, anObject);
877
 
        }
878
 
    }
879
 
  return;
880
 
}
881
 
 
882
 
#endif  /* defined(REFCNT_LOCAL) || defined(CACHE_ZONE) */
883
 
 
 
726
      AREM(o->class_pointer, o);
 
727
      AADD(c, o);
884
728
#endif  /* GS_WITH_GC */
 
729
      o->class_pointer = c;
 
730
    }
 
731
}
 
732
 
885
733
 
886
734
BOOL
887
735
NSShouldRetainWithZone (NSObject *anObject, NSZone *requestedZone)
890
738
  return YES;
891
739
#else
892
740
  return (!requestedZone || requestedZone == NSDefaultMallocZone()
893
 
    || GSObjCZone(anObject) == requestedZone);
 
741
    || [anObject zone] == requestedZone);
894
742
#endif
895
743
}
896
744
 
897
745
 
898
746
 
899
 
 
 
747
/* FIXME ... the following code is a hack for the gnu runtime only
 
748
 */
900
749
struct objc_method_description_list {
901
750
  int count;
902
751
  struct objc_method_description list[1];
903
752
};
904
 
typedef struct {
905
 
  @defs(Protocol)
906
 
} *pcl;
 
753
 
 
754
/* Must have same layout as ivars of Protocol class
 
755
 */
 
756
struct protocol_class {
 
757
  Class isa;
 
758
  char  *protocol_name;
 
759
  struct objc_protocol_list *protocol_list;
 
760
  struct objc_method_description_list *instance_methods;
 
761
  struct objc_method_description_list *class_methods;
 
762
};
907
763
 
908
764
struct objc_method_description *
909
 
GSDescriptionForInstanceMethod(pcl self, SEL aSel)
 
765
GSDescriptionForInstanceMethod(Protocol *self, SEL aSel)
910
766
{
 
767
  struct protocol_class *pcl = (struct protocol_class*)self;
911
768
  int i;
912
769
  struct objc_protocol_list     *p_list;
913
 
  const char                    *name = GSNameFromSelector(aSel);
 
770
  const char                    *name = sel_getName(aSel);
914
771
  struct objc_method_description *result;
915
772
 
916
 
  if (self->instance_methods != 0)
 
773
  if (pcl->instance_methods != 0)
917
774
    {
918
 
      for (i = 0; i < self->instance_methods->count; i++)
 
775
      for (i = 0; i < pcl->instance_methods->count; i++)
919
776
        {
920
 
          if (!strcmp ((char*)self->instance_methods->list[i].name, name))
921
 
            return &(self->instance_methods->list[i]);
 
777
          if (!strcmp ((char*)pcl->instance_methods->list[i].name, name))
 
778
            return &(pcl->instance_methods->list[i]);
922
779
        }
923
780
    }
924
 
  for (p_list = self->protocol_list; p_list != 0; p_list = p_list->next)
 
781
  for (p_list = pcl->protocol_list; p_list != 0; p_list = p_list->next)
925
782
    {
926
783
      for (i = 0; i < p_list->count; i++)
927
784
        {
928
 
          result = GSDescriptionForInstanceMethod((pcl)p_list->list[i], aSel);
 
785
          result = GSDescriptionForInstanceMethod(p_list->list[i], aSel);
929
786
          if (result)
930
787
            {
931
788
              return result;
937
794
}
938
795
 
939
796
struct objc_method_description *
940
 
GSDescriptionForClassMethod(pcl self, SEL aSel)
 
797
GSDescriptionForClassMethod(Protocol *self, SEL aSel)
941
798
{
 
799
  struct protocol_class *pcl = (struct protocol_class*)self;
942
800
  int i;
943
801
  struct objc_protocol_list     *p_list;
944
 
  const char                    *name = GSNameFromSelector(aSel);
 
802
  const char                    *name = sel_getName(aSel);
945
803
  struct objc_method_description *result;
946
804
 
947
 
  if (self->class_methods != 0)
 
805
  if (pcl->class_methods != 0)
948
806
    {
949
 
      for (i = 0; i < self->class_methods->count; i++)
 
807
      for (i = 0; i < pcl->class_methods->count; i++)
950
808
        {
951
 
          if (!strcmp ((char*)self->class_methods->list[i].name, name))
952
 
            return &(self->class_methods->list[i]);
 
809
          if (!strcmp ((char*)pcl->class_methods->list[i].name, name))
 
810
            return &(pcl->class_methods->list[i]);
953
811
        }
954
812
    }
955
 
  for (p_list = self->protocol_list; p_list != 0; p_list = p_list->next)
 
813
  for (p_list = pcl->protocol_list; p_list != 0; p_list = p_list->next)
956
814
    {
957
815
      for (i = 0; i < p_list->count; i++)
958
816
        {
959
 
          result = GSDescriptionForClassMethod((pcl)p_list->list[i], aSel);
 
817
          result = GSDescriptionForClassMethod(p_list->list[i], aSel);
960
818
          if (result)
961
819
            {
962
820
              return result;
971
829
 
972
830
- (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel
973
831
{
974
 
  return GSDescriptionForInstanceMethod((pcl)self, aSel);
 
832
  return GSDescriptionForInstanceMethod(self, aSel);
975
833
}
976
834
 
977
835
- (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel;
978
836
{
979
 
  return GSDescriptionForClassMethod((pcl)self, aSel);
 
837
  return GSDescriptionForClassMethod(self, aSel);
980
838
}
981
839
 
982
840
@end
1046
904
{
1047
905
  if (allocationLock == 0)
1048
906
    {
1049
 
#if defined(REFCNT_LOCAL) && !defined(GSATOMICREAD)
1050
 
      unsigned  i;
 
907
#if !defined(GSATOMICREAD)
 
908
      NSUInteger        i;
1051
909
 
1052
910
      for (i = 0; i < LOCKCOUNT; i++)
1053
911
        {
1054
 
          allocationLocks[i] = objc_mutex_allocate();
 
912
          allocationLocks[i] = [NSLock new];
1055
913
        }
1056
914
#endif
1057
 
      allocationLock = objc_mutex_allocate();
 
915
      allocationLock = [NSLock new];
1058
916
    }
1059
917
}
1060
918
 
1061
919
#if     GS_WITH_GC
1062
 
/**
1063
 
 * A utility method used when garbage collection is enabled.  Can be ignored.
1064
 
 */
1065
 
+ (BOOL) requiresTypedMemory
1066
 
{
1067
 
  return NO;
1068
 
}
1069
 
#endif
1070
 
 
1071
 
/**
1072
 
 * This message is sent to a class once just before it is used for the first
1073
 
 * time.  If class has a superclass, its implementation of +initialize is
1074
 
 * called first.  You can implement +initialize in your own class if you need
1075
 
 * to.  NSObject's implementation handles essential root object and base
1076
 
 * library initialization.
1077
 
 */
 
920
/* Function to log Boehm GC warnings
 
921
 * NB. This must not allocate any collectable memory as it may result
 
922
 * in a deadlock in the garbage collecting library.
 
923
 */
 
924
static void
 
925
GSGarbageCollectorLog(char *msg, GC_word arg)
 
926
{
 
927
  char  buf[strlen(msg)+1024];
 
928
  sprintf(buf, msg, (unsigned long)arg);
 
929
  fprintf(stderr, "Garbage collector: %s", buf);
 
930
}
 
931
#endif
 
932
 
 
933
/**
 
934
 * Semi-private function in libobjc2 that initialises the classes used for
 
935
 * blocks.
 
936
 */
 
937
#ifndef __MINGW__
 
938
BOOL 
 
939
objc_create_block_classes_as_subclasses_of(Class super) __attribute__((weak));
 
940
#endif
 
941
 
 
942
+ (void)load
 
943
{
 
944
#ifndef __MINGW__
 
945
  /* When NSObject is loaded, register it as the superclass of the block
 
946
   * classes */
 
947
  if (objc_create_block_classes_as_subclasses_of)
 
948
    objc_create_block_classes_as_subclasses_of(self);
 
949
#endif
 
950
}
 
951
 
1078
952
+ (void) initialize
1079
953
{
1080
954
  if (self == [NSObject class])
1081
955
    {
1082
 
#ifdef __MINGW32__
1083
 
      // See libgnustep-base-entry.m
1084
 
      extern void gnustep_base_socket_init(void);       
1085
 
      gnustep_base_socket_init();       
1086
 
#else
 
956
#if     GS_WITH_GC
 
957
      /* Make sure that the garbage collection library is initialised.
 
958
       * This is not necessary on most platforms, but is good practice.
 
959
       */
 
960
      GC_init();
 
961
      GC_set_warn_proc(GSGarbageCollectorLog);
 
962
#endif
 
963
 
 
964
#ifdef __MINGW__
 
965
      {
 
966
        // See libgnustep-base-entry.m
 
967
        extern void gnustep_base_socket_init(void);     
 
968
        gnustep_base_socket_init();     
 
969
      }
 
970
#else /* __MINGW__ */
1087
971
 
1088
972
#ifdef  SIGPIPE
1089
973
    /*
1113
997
            fprintf(stderr, "Unable to retrieve information about SIGPIPE\n");
1114
998
          }
1115
999
      }
1116
 
#else
 
1000
#else /* HAVE_SIGACTION */
1117
1001
      {
1118
 
        void    (*handler)(int);
 
1002
        void    (*handler)(NSInteger);
1119
1003
 
1120
1004
        handler = signal(SIGPIPE, SIG_IGN);
1121
1005
        if (handler != SIG_DFL)
1123
1007
            signal(SIGPIPE, handler);
1124
1008
          }
1125
1009
      }
1126
 
#endif
1127
 
#endif
 
1010
#endif /* HAVE_SIGACTION */
 
1011
#endif /* SIGPIPE */
 
1012
#endif /* __MINGW__ */
 
1013
 
 
1014
#if     GS_WITH_GC
 
1015
      finalize_sel = @selector(finalize);
 
1016
      finalize_imp = get_imp(self, finalize_sel);
1128
1017
#endif
1129
1018
 
1130
1019
#if defined(__FreeBSD__) && defined(__i386__)
1131
1020
      // Manipulate the FPU to add the exception mask. (Fixes SIGFPE
1132
1021
      // problems on *BSD)
1133
1022
      // Note this only works on x86
1134
 
 
1135
 
      {
1136
 
        volatile short cw;
1137
 
 
1138
 
        __asm__ volatile ("fstcw (%0)" : : "g" (&cw));
1139
 
        cw |= 1; /* Mask 'invalid' exception */
1140
 
        __asm__ volatile ("fldcw (%0)" : : "g" (&cw));
1141
 
      }
 
1023
      fedisableexcept(FE_INVALID);
1142
1024
#endif
1143
1025
 
1144
 
 
1145
1026
#ifdef HAVE_LOCALE_H
1146
1027
      GSSetLocaleC(LC_ALL, "");         // Set up locale from environment.
1147
1028
#endif
1149
1030
      // Create the global lock
1150
1031
      gnustep_global_lock = [NSRecursiveLock new];
1151
1032
 
 
1033
      // Behavior debugging
 
1034
      GSObjCBehaviorDebug(GSPrivateEnvironmentFlag("GNUSTEP_BEHAVIOR_DEBUG",
 
1035
        GSObjCBehaviorDebug(-1)));
 
1036
 
1152
1037
      // Zombie management stuff.
1153
1038
      zombieMap = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
1154
1039
        NSNonOwnedPointerMapValueCallBacks, 0);
1159
1044
      autorelease_class = [NSAutoreleasePool class];
1160
1045
      autorelease_sel = @selector(addObject:);
1161
1046
      autorelease_imp = [autorelease_class methodForSelector: autorelease_sel];
1162
 
#if     GS_WITH_GC == 0
1163
 
#if     !defined(REFCNT_LOCAL)
1164
 
      GSIMapInitWithZoneAndCapacity(&retain_counts,
1165
 
        NSDefaultMallocZone(), 1024);
1166
 
#endif
1167
 
#endif
1168
1047
      NSConstantStringClass = [NSString constantStringClass];
1169
1048
      GSPrivateBuildStrings();
1170
1049
      [[NSNotificationCenter defaultCenter]
1424
1303
  NSDeallocateObject (self);
1425
1304
}
1426
1305
 
 
1306
- (void) finalize
 
1307
{
 
1308
  return;
 
1309
}
 
1310
 
1427
1311
/**
1428
1312
 *  This method is an anachronism.  Do not use it.
1429
1313
 */
1456
1340
 */
1457
1341
+ (Class) superclass
1458
1342
{
1459
 
  return GSObjCSuper(self);
 
1343
  return class_getSuperclass(self);
1460
1344
}
1461
1345
 
1462
1346
/**
1464
1348
 */
1465
1349
- (Class) superclass
1466
1350
{
1467
 
  return GSObjCSuper(GSObjCClass(self));
 
1351
  return class_getSuperclass(object_getClass(self));
1468
1352
}
1469
1353
 
1470
1354
/**
1505
1389
  for (proto_list = ((struct objc_class*)self)->protocols;
1506
1390
       proto_list; proto_list = proto_list->next)
1507
1391
    {
1508
 
      unsigned int i;
 
1392
      NSUInteger i;
1509
1393
 
1510
1394
      for (i = 0; i < proto_list->count; i++)
1511
1395
        {
1564
1448
    [NSException raise: NSInvalidArgumentException
1565
1449
                format: @"%@ null selector given", NSStringFromSelector(_cmd)];
1566
1450
  /*
1567
 
   *    If 'self' is an instance, GSObjCClass() will get the class,
 
1451
   *    If 'self' is an instance, object_getClass() will get the class,
1568
1452
   *    and get_imp() will get the instance method.
1569
 
   *    If 'self' is a class, GSObjCClass() will get the meta-class,
 
1453
   *    If 'self' is a class, object_getClass() will get the meta-class,
1570
1454
   *    and get_imp() will get the class method.
1571
1455
   */
1572
 
  return get_imp(GSObjCClass(self), aSelector);
 
1456
  return get_imp(object_getClass(self), aSelector);
1573
1457
}
1574
1458
 
1575
1459
/**
1599
1483
 */
1600
1484
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
1601
1485
{
1602
 
  const char            *selTypes;
1603
1486
  const char            *types;
1604
1487
  struct objc_method    *mth;
1605
1488
  Class                 c;
1608
1491
    [NSException raise: NSInvalidArgumentException
1609
1492
                format: @"%@ null selector given", NSStringFromSelector(_cmd)];
1610
1493
 
1611
 
  selTypes = sel_get_type(aSelector);
1612
 
  c = (GSObjCIsInstance(self) ? GSObjCClass(self) : (Class)self);
 
1494
  c = (GSObjCIsInstance(self) ? object_getClass(self) : (Class)self);
1613
1495
  mth = GSGetMethod(c, aSelector, GSObjCIsInstance(self), YES);
1614
1496
 
1615
1497
  if (mth == 0)
1635
1517
 
1636
1518
      while (found == NO && protocols != 0)
1637
1519
        {
1638
 
          unsigned      i = 0;
 
1520
          NSUInteger    i = 0;
1639
1521
 
1640
1522
          while (found == NO && i < protocols->count)
1641
1523
            {
1665
1547
    {
1666
1548
      return nil;
1667
1549
    }
1668
 
  else if (selTypes != 0 && GSSelectorTypesMatch(selTypes, types) == NO)
1669
 
    {
1670
 
      [NSException raise: NSInternalInconsistencyException
1671
 
        format: @"[%@%c%@] selector types (%s) don't match method types (%s)",
1672
 
        NSStringFromClass(c), (GSObjCIsInstance(self) ? '-' : '+'),
1673
 
        NSStringFromSelector(aSelector), selTypes, types];
1674
 
    }
1675
1550
  return [NSMethodSignature signatureWithObjCTypes: types];
1676
1551
}
1677
1552
 
1682
1557
- (NSString*) description
1683
1558
{
1684
1559
  return [NSString stringWithFormat: @"<%s: %p>",
1685
 
    GSClassNameFromObject(self), self];
 
1560
    class_getName([self class]), self];
1686
1561
}
1687
1562
 
1688
1563
/**
1717
1592
              format: @"%s(%s) does not recognize %s",
1718
1593
               GSClassNameFromObject(self),
1719
1594
               GSObjCIsInstance(self) ? "instance" : "class",
1720
 
               aSelector ? GSNameFromSelector(aSelector) : "(null)"];
 
1595
               aSelector ? sel_getName(aSelector) : "(null)"];
1721
1596
}
1722
1597
 
1723
1598
- (retval_t) forward: (SEL)aSel : (arglist_t)argFrame
1741
1616
 */
1742
1617
- (void) forwardInvocation: (NSInvocation*)anInvocation
1743
1618
{
 
1619
  id target = [self forwardingTargetForSelector: [anInvocation selector]];
 
1620
 
 
1621
  if (nil != target)
 
1622
    {
 
1623
      [anInvocation invokeWithTarget: target];
 
1624
      return;
 
1625
    }
1744
1626
  [self doesNotRecognizeSelector: [anInvocation selector]];
1745
1627
  return;
1746
1628
}
1821
1703
#if     GS_WITH_GC == 0
1822
1704
  if (double_release_check_enabled)
1823
1705
    {
1824
 
      unsigned release_count;
1825
 
      unsigned retain_count = [self retainCount];
 
1706
      NSUInteger release_count;
 
1707
      NSUInteger retain_count = [self retainCount];
1826
1708
      release_count = [autorelease_class autoreleaseCountForObject:self];
1827
1709
      if (release_count > retain_count)
1828
1710
        [NSException
1860
1742
 * The default implementation returns a value based on the address
1861
1743
 * of the instance.
1862
1744
 */
1863
 
- (unsigned) hash
 
1745
- (NSUInteger) hash
1864
1746
{
1865
1747
  /*
1866
1748
   * Ideally we would shift left to lose any zero bits produced by the
1869
1751
   * In the absence of detailed information, pick a reasonable value
1870
1752
   * assuming the object will be aligned to an eight byte boundary.
1871
1753
   */
1872
 
  return (unsigned)(uintptr_t)self >> 3;
 
1754
  return (NSUInteger)(uintptr_t)self >> 3;
1873
1755
}
1874
1756
 
1875
1757
/**
1900
1782
 */
1901
1783
- (BOOL) isKindOfClass: (Class)aClass
1902
1784
{
1903
 
  Class class = GSObjCClass(self);
 
1785
  Class class = object_getClass(self);
1904
1786
 
1905
1787
  return GSObjCIsKindOf(class, aClass);
1906
1788
}
1918
1800
 */
1919
1801
- (BOOL) isMemberOfClass: (Class)aClass
1920
1802
{
1921
 
  return (GSObjCClass(self) == aClass) ? YES : NO;
 
1803
  return (object_getClass(self) == aClass) ? YES : NO;
1922
1804
}
1923
1805
 
1924
1806
/**
1954
1836
    [NSException raise: NSInvalidArgumentException
1955
1837
                format: @"%@ null selector given", NSStringFromSelector(_cmd)];
1956
1838
 
1957
 
  msg = get_imp(GSObjCClass(self), aSelector);
 
1839
  msg = get_imp(object_getClass(self), aSelector);
1958
1840
  if (!msg)
1959
1841
    {
1960
1842
      [NSException raise: NSGenericException
1961
1843
                   format: @"invalid selector passed to %s",
1962
 
                     GSNameFromSelector(_cmd)];
 
1844
                     sel_getName(_cmd)];
1963
1845
      return nil;
1964
1846
    }
1965
1847
  return (*msg)(self, aSelector);
1979
1861
    [NSException raise: NSInvalidArgumentException
1980
1862
                format: @"%@ null selector given", NSStringFromSelector(_cmd)];
1981
1863
 
1982
 
  msg = get_imp(GSObjCClass(self), aSelector);
 
1864
  msg = get_imp(object_getClass(self), aSelector);
1983
1865
  if (!msg)
1984
1866
    {
1985
1867
      [NSException raise: NSGenericException
1986
1868
                   format: @"invalid selector passed to %s",
1987
 
                   GSNameFromSelector(_cmd)];
 
1869
                   sel_getName(_cmd)];
1988
1870
      return nil;
1989
1871
    }
1990
1872
 
2007
1889
    [NSException raise: NSInvalidArgumentException
2008
1890
                format: @"%@ null selector given", NSStringFromSelector(_cmd)];
2009
1891
 
2010
 
  msg = get_imp(GSObjCClass(self), aSelector);
 
1892
  msg = get_imp(object_getClass(self), aSelector);
2011
1893
  if (!msg)
2012
1894
    {
2013
1895
      [NSException raise: NSGenericException
2014
 
                  format: @"invalid selector passed to %s", GSNameFromSelector(_cmd)];
 
1896
                  format: @"invalid selector passed to %s", sel_getName(_cmd)];
2015
1897
      return nil;
2016
1898
    }
2017
1899
 
2105
1987
 * By convention, objects which should (or can) never be deallocated
2106
1988
 * return the maximum unsigned integer value.
2107
1989
 */
2108
 
- (unsigned) retainCount
 
1990
- (NSUInteger) retainCount
2109
1991
{
2110
1992
#if     GS_WITH_GC
2111
1993
  return UINT_MAX;
2119
2001
 * the maximum unsigned integer value, as classes can not be deallocated
2120
2002
 * the retain count mechanism is a dummy system for them.
2121
2003
 */
2122
 
+ (unsigned) retainCount
 
2004
+ (NSUInteger) retainCount
2123
2005
{
2124
2006
  return UINT_MAX;
2125
2007
}
2137
2019
 */
2138
2020
- (NSZone*) zone
2139
2021
{
2140
 
  return GSObjCZone(self);
 
2022
#if     GS_WITH_GC
 
2023
  /* MacOS-X 10.5 seems to return the default malloc zone if GC is enabled.
 
2024
   */
 
2025
  return NSDefaultMallocZone();
 
2026
#else
 
2027
  return (((obj)self)[-1]).zone;
 
2028
#endif
2141
2029
}
2142
2030
 
2143
2031
/**
2160
2048
  return self;
2161
2049
}
2162
2050
 
2163
 
/**
2164
 
 *  Returns the version number of the receiving class.  This will default to
2165
 
 *  a number assigned by the Objective C compiler if [NSObject -setVersion] has
2166
 
 *  not been called.
2167
 
 */
2168
 
+ (int) version
2169
 
{
2170
 
  return class_get_version(self);
 
2051
+ (BOOL) resolveClassMethod: (SEL)name
 
2052
{
 
2053
  return NO;
 
2054
}
 
2055
 
 
2056
+ (BOOL) resolveInstanceMethod: (SEL)name
 
2057
{
 
2058
  return NO;
2171
2059
}
2172
2060
 
2173
2061
/**
2174
2062
 * Sets the version number of the receiving class.  Should be nonnegative.
2175
2063
 */
2176
 
+ (id) setVersion: (int)aVersion
 
2064
+ (id) setVersion: (NSInteger)aVersion
2177
2065
{
2178
2066
  if (aVersion < 0)
2179
2067
    [NSException raise: NSInvalidArgumentException
2183
2071
  return self;
2184
2072
}
2185
2073
 
 
2074
/**
 
2075
 *  Returns the version number of the receiving class.  This will default to
 
2076
 *  a number assigned by the Objective C compiler if [NSObject -setVersion] has
 
2077
 *  not been called.
 
2078
 */
 
2079
+ (NSInteger) version
 
2080
{
 
2081
  return class_get_version(self);
 
2082
}
 
2083
 
 
2084
- (id) autoContentAccessingProxy
 
2085
{
 
2086
  return AUTORELEASE([[GSContentAccessingProxy alloc] initWithObject: self]);
 
2087
}
 
2088
 
 
2089
- (id) forwardingTargetForSelector:(SEL)aSelector
 
2090
{
 
2091
  return nil;
 
2092
}
2186
2093
@end
2187
2094
 
2188
2095
 
2296
2203
               format: @"%s(%s) does not recognize %s",
2297
2204
               GSClassNameFromObject(self),
2298
2205
               GSObjCIsInstance(self) ? "instance" : "class",
2299
 
               aSel ? GSNameFromSelector(aSel) : "(null)"];
 
2206
               aSel ? sel_getName(aSel) : "(null)"];
2300
2207
  return nil;
2301
2208
}
2302
2209
 
2321
2228
 */
2322
2229
@implementation NSObject (GNUstep)
2323
2230
 
2324
 
/* GNU Object class compatibility */
2325
 
 
2326
 
/**
2327
 
 * Called to change the class used for autoreleasing objects.
2328
 
 */
2329
 
+ (void) setAutoreleaseClass: (Class)aClass
2330
 
{
2331
 
  autorelease_class = aClass;
2332
 
  autorelease_imp = [self instanceMethodForSelector: autorelease_sel];
2333
 
}
2334
 
 
2335
 
/**
2336
 
 * returns the class used to autorelease objects.
2337
 
 */
2338
 
+ (Class) autoreleaseClass
2339
 
{
2340
 
  return autorelease_class;
2341
 
}
2342
 
 
2343
2231
/**
2344
2232
 * Enables runtime checking of retain/release/autorelease operations.<br />
2345
2233
 * <p>Whenever either -autorelease or -release is called, the contents of any
2384
2272
 * level information.
2385
2273
 */
2386
2274
- (NSString*) descriptionWithLocale: (NSDictionary*)aLocale
2387
 
                             indent: (unsigned)level
 
2275
                             indent: (NSUInteger)level
2388
2276
{
2389
2277
  return [self descriptionWithLocale: aLocale];
2390
2278
}
2391
2279
 
2392
2280
+ (NSString*) descriptionWithLocale: (NSDictionary*)aLocale
2393
 
                             indent: (unsigned)level
 
2281
                             indent: (NSUInteger)level
2394
2282
{
2395
2283
  return [self descriptionWithLocale: aLocale];
2396
2284
}
2407
2295
 
2408
2296
- (BOOL) isClass
2409
2297
{
2410
 
  return GSObjCIsClass((Class)self);
2411
 
}
2412
 
 
2413
 
- (BOOL) isInstance
2414
 
{
2415
 
  return GSObjCIsInstance(self);
 
2298
  return class_isMetaClass(object_getClass(self));
2416
2299
}
2417
2300
 
2418
2301
- (BOOL) isMemberOfClassNamed: (const char*)aClassName
2419
2302
{
2420
2303
  return ((aClassName!=NULL)
2421
 
          &&!strcmp(GSNameFromClass(GSObjCClass(self)), aClassName));
 
2304
          &&!strcmp(class_getName(object_getClass(self)), aClassName));
2422
2305
}
2423
2306
 
2424
2307
+ (struct objc_method_description *) descriptionForInstanceMethod: (SEL)aSel
2439
2322
 
2440
2323
  return ((struct objc_method_description *)
2441
2324
          GSGetMethod((GSObjCIsInstance(self)
2442
 
                       ? GSObjCClass(self) : (Class)self),
 
2325
                       ? object_getClass(self) : (Class)self),
2443
2326
                      aSel,
2444
2327
                      GSObjCIsInstance(self),
2445
2328
                      YES));
2446
2329
}
2447
2330
 
2448
 
/**
2449
 
 * Transmutes the receiver into an immutable version of the same object
2450
 
 * and returns the result.<br />
2451
 
 * If the receiver is not a mutable object or cannot be simply transmuted,
2452
 
 * then this method either returns the receiver unchanged or,
2453
 
 * if the force flag is set to YES, returns an autoreleased copy of the
2454
 
 * receiver.<br />
2455
 
 * Mutable classes should override this default implementation.<br />
2456
 
 * This method is used in methods which are declared to return immutable
2457
 
 * objects (eg. an NSArray), but which create and build mutable ones
2458
 
 * internally.
2459
 
 */
2460
 
- (id) makeImmutableCopyOnFail: (BOOL)force
2461
 
{
2462
 
  if (force == YES)
2463
 
    {
2464
 
      return AUTORELEASE([self copy]);
2465
 
    }
2466
 
  return self;
2467
 
}
2468
 
 
2469
 
/**
2470
 
 * Changes the class of the receiver (the 'isa' pointer) to be aClassObject,
2471
 
 * but only if the receiver is an instance of a subclass of aClassObject
2472
 
 * which has not added extra instance variables.<br />
2473
 
 * Returns zero on failure, or the old class on success.
2474
 
 */
2475
 
- (Class) transmuteClassTo: (Class)aClassObject
2476
 
{
2477
 
  if (GSObjCIsInstance(self) == YES)
2478
 
    if (class_is_class(aClassObject))
2479
 
      if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
2480
 
        if ([self isKindOfClass: aClassObject])
2481
 
          {
2482
 
            Class old_isa = isa;
2483
 
            isa = aClassObject;
2484
 
            return old_isa;
2485
 
          }
2486
 
  return 0;
2487
 
}
2488
 
 
2489
 
+ (int) streamVersion: (TypedStream*)aStream
 
2331
+ (NSInteger) streamVersion: (TypedStream*)aStream
2490
2332
{
2491
2333
#ifndef NeXT_RUNTIME
2492
2334
  if (aStream->mode == OBJC_READONLY)
2595
2437
@implementation NSZombie
2596
2438
- (Class) class
2597
2439
{
2598
 
  return object_get_class(self);
 
2440
  return (Class)isa;
 
2441
}
 
2442
- (Class) originalClass
 
2443
{
 
2444
  return NSMapGet(zombieMap, (void*)self);
2599
2445
}
2600
2446
- (retval_t) forward:(SEL)aSel :(arglist_t)argFrame
2601
2447
{
2608
2454
}
2609
2455
- (void) forwardInvocation: (NSInvocation*)anInvocation
2610
2456
{
2611
 
  unsigned      size = [[anInvocation methodSignature] methodReturnLength];
 
2457
  NSUInteger    size = [[anInvocation methodSignature] methodReturnLength];
2612
2458
  unsigned char v[size];
2613
2459
 
2614
2460
  memset(v, '\0', size);
2620
2466
{
2621
2467
  Class c;
2622
2468
 
2623
 
  if (allocationLock != 0)
2624
 
    {
2625
 
      objc_mutex_lock(allocationLock);
2626
 
    }
 
2469
  [allocationLock lock];
2627
2470
  c = NSMapGet(zombieMap, (void*)self);
2628
 
  if (allocationLock != 0)
2629
 
    {
2630
 
      objc_mutex_unlock(allocationLock);
2631
 
    }
 
2471
  [allocationLock unlock];
2632
2472
  return [c instanceMethodSignatureForSelector: aSelector];
2633
2473
}
2634
2474
@end
2635
2475
 
 
2476
@implementation GSContentAccessingProxy 
 
2477
- (void) dealloc
 
2478
{
 
2479
  [object endContentAccess];
 
2480
  [super dealloc];
 
2481
}
 
2482
 
 
2483
- (void) finalize
 
2484
{
 
2485
  [object endContentAccess];
 
2486
}
 
2487
 
 
2488
- (id) forwardingTargetForSelector: (SEL)aSelector
 
2489
{
 
2490
  return object;
 
2491
}
 
2492
/* Support for legacy runtimes... */
 
2493
- (void) forwardInvocation: (NSInvocation*)anInvocation
 
2494
{
 
2495
  [anInvocation invokeWithTarget: object];
 
2496
}
 
2497
 
 
2498
- (id) initWithObject: (id)anObject
 
2499
{
 
2500
  ASSIGN(object, anObject);
 
2501
  [object beginContentAccess];
 
2502
  return self;
 
2503
}
 
2504
 
 
2505
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
 
2506
{
 
2507
  return [object methodSignatureForSelector: aSelector];
 
2508
}
 
2509
@end