2002-08-20 15:32:13 +00:00
|
|
|
|
/** Implementation of NSObject for GNUStep
|
2010-03-23 00:03:21 +00:00
|
|
|
|
Copyright (C) 1994-2010 Free Software Foundation, Inc.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1996-04-17 20:17:45 +00:00
|
|
|
|
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
1995-01-26 17:55:52 +00:00
|
|
|
|
Date: August 1994
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1996-05-12 00:56:10 +00:00
|
|
|
|
This file is part of the GNUstep Base Library.
|
1995-01-26 17:55:52 +00:00
|
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
2007-09-14 11:36:11 +00:00
|
|
|
|
modify it under the terms of the GNU Lesser General Public
|
1995-01-26 17:55:52 +00:00
|
|
|
|
License as published by the Free Software Foundation; either
|
2008-06-08 10:38:33 +00:00
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1995-01-26 17:55:52 +00:00
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
Library General Public License for more details.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2007-09-14 11:36:11 +00:00
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
1995-01-26 17:55:52 +00:00
|
|
|
|
License along with this library; if not, write to the Free
|
2006-05-15 12:07:35 +00:00
|
|
|
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
|
Boston, MA 02111 USA.
|
2001-12-18 16:54:15 +00:00
|
|
|
|
|
|
|
|
|
<title>NSObject class reference</title>
|
|
|
|
|
$Date$ $Revision$
|
2005-02-22 11:22:44 +00:00
|
|
|
|
*/
|
1995-01-26 17:55:52 +00:00
|
|
|
|
|
2007-03-05 16:09:46 +00:00
|
|
|
|
/* On some versions of mingw we need to work around bad function declarations
|
|
|
|
|
* by defining them away and doing the declarations ourself later.
|
|
|
|
|
*/
|
2008-11-17 13:45:32 +00:00
|
|
|
|
#ifndef _WIN64
|
2007-03-05 16:09:46 +00:00
|
|
|
|
#define InterlockedIncrement BadInterlockedIncrement
|
|
|
|
|
#define InterlockedDecrement BadInterlockedDecrement
|
2008-11-17 13:45:32 +00:00
|
|
|
|
#endif
|
2007-03-05 16:09:46 +00:00
|
|
|
|
|
2010-02-19 08:12:46 +00:00
|
|
|
|
#import "common.h"
|
1995-03-23 03:31:30 +00:00
|
|
|
|
#include <objc/Protocol.h>
|
2010-02-17 11:47:06 +00:00
|
|
|
|
#import "Foundation/NSMethodSignature.h"
|
|
|
|
|
#import "Foundation/NSInvocation.h"
|
|
|
|
|
#import "Foundation/NSLock.h"
|
|
|
|
|
#import "Foundation/NSAutoreleasePool.h"
|
|
|
|
|
#import "Foundation/NSArray.h"
|
|
|
|
|
#import "Foundation/NSException.h"
|
|
|
|
|
#import "Foundation/NSPortCoder.h"
|
|
|
|
|
#import "Foundation/NSDistantObject.h"
|
|
|
|
|
#import "Foundation/NSThread.h"
|
|
|
|
|
#import "Foundation/NSNotification.h"
|
|
|
|
|
#import "Foundation/NSMapTable.h"
|
|
|
|
|
#import "GNUstepBase/GSLocale.h"
|
2011-06-19 09:26:03 +00:00
|
|
|
|
#import "GNUstepBase/NSObject+GNUstepBase.h"
|
2002-12-05 04:24:43 +00:00
|
|
|
|
#ifdef HAVE_LOCALE_H
|
|
|
|
|
#include <locale.h>
|
|
|
|
|
#endif
|
1995-03-12 15:40:22 +00:00
|
|
|
|
|
2003-10-16 18:31:38 +00:00
|
|
|
|
#ifdef HAVE_SIGNAL_H
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef HAVE_SYS_SIGNAL_H
|
|
|
|
|
#include <sys/signal.h>
|
|
|
|
|
#endif
|
2011-04-03 09:54:57 +00:00
|
|
|
|
|
|
|
|
|
#if __GNUC__ >= 4
|
|
|
|
|
#if defined(__FreeBSD__)
|
2009-08-15 21:44:21 +00:00
|
|
|
|
#include <fenv.h>
|
|
|
|
|
#endif
|
2011-04-03 09:54:57 +00:00
|
|
|
|
#endif // __GNUC__
|
2003-10-16 18:31:38 +00:00
|
|
|
|
|
2011-05-28 14:51:40 +00:00
|
|
|
|
#ifdef __OBJC_GC__
|
|
|
|
|
#include <objc/objc-auto.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-02-10 10:52:54 +00:00
|
|
|
|
#define IN_NSOBJECT_M 1
|
2010-02-17 11:47:06 +00:00
|
|
|
|
#import "GSPrivate.h"
|
2002-01-30 13:05:35 +00:00
|
|
|
|
|
2011-06-29 13:13:15 +00:00
|
|
|
|
|
|
|
|
|
#ifdef __GNUSTEP_RUNTIME__
|
|
|
|
|
#include <objc/capabilities.h>
|
|
|
|
|
#include <objc/hooks.h>
|
|
|
|
|
#ifdef OBJC_CAP_ARC
|
|
|
|
|
#include <objc/objc-arc.h>
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-09-07 11:47:45 +00:00
|
|
|
|
/* When this is `YES', every call to release/autorelease, checks to
|
|
|
|
|
make sure isn't being set up to release itself too many times.
|
|
|
|
|
This does not need mutex protection. */
|
|
|
|
|
static BOOL double_release_check_enabled = NO;
|
|
|
|
|
|
|
|
|
|
/* The Class responsible for handling autorelease's. This does not
|
|
|
|
|
need mutex protection, since it is simply a pointer that gets read
|
|
|
|
|
and set. */
|
|
|
|
|
static id autorelease_class = nil;
|
|
|
|
|
static SEL autorelease_sel;
|
|
|
|
|
static IMP autorelease_imp;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-06-05 12:39:28 +00:00
|
|
|
|
#if GS_WITH_GC
|
|
|
|
|
|
2011-02-27 17:53:14 +00:00
|
|
|
|
#include <gc/gc.h>
|
|
|
|
|
#include <gc/gc_typed.h>
|
2002-06-05 12:39:28 +00:00
|
|
|
|
|
2002-05-28 05:23:36 +00:00
|
|
|
|
#endif
|
1998-11-12 10:58:17 +00:00
|
|
|
|
|
2011-04-05 12:13:12 +00:00
|
|
|
|
static SEL finalize_sel;
|
|
|
|
|
static IMP finalize_imp;
|
2001-06-06 15:18:28 +00:00
|
|
|
|
static Class NSConstantStringClass;
|
2000-10-09 04:41:18 +00:00
|
|
|
|
|
1998-10-21 11:56:58 +00:00
|
|
|
|
@class NSDataMalloc;
|
|
|
|
|
@class NSMutableDataMalloc;
|
|
|
|
|
|
2005-07-08 11:48:37 +00:00
|
|
|
|
@interface NSZombie
|
|
|
|
|
{
|
|
|
|
|
Class isa;
|
|
|
|
|
}
|
|
|
|
|
- (Class) class;
|
|
|
|
|
- (void) forwardInvocation: (NSInvocation*)anInvocation;
|
|
|
|
|
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector;
|
|
|
|
|
@end
|
|
|
|
|
|
2011-05-26 18:37:58 +00:00
|
|
|
|
@interface GSContentAccessingProxy : NSProxy
|
2009-09-10 20:14:42 +00:00
|
|
|
|
{
|
2009-09-12 07:37:00 +00:00
|
|
|
|
NSObject<NSDiscardableContent> *object;
|
2009-09-10 20:14:42 +00:00
|
|
|
|
}
|
2009-09-12 07:37:00 +00:00
|
|
|
|
- (id) initWithObject: (id)anObject;
|
2009-09-10 20:14:42 +00:00
|
|
|
|
@end
|
|
|
|
|
|
2002-03-27 09:55:57 +00:00
|
|
|
|
/*
|
2011-05-26 18:37:58 +00:00
|
|
|
|
* allocationLock is needed when running multi-threaded for
|
2009-03-06 11:01:42 +00:00
|
|
|
|
* protecting the map table of zombie information.
|
2002-03-27 09:55:57 +00:00
|
|
|
|
*/
|
2009-09-10 20:14:42 +00:00
|
|
|
|
static NSLock *allocationLock;
|
2002-03-27 09:55:57 +00:00
|
|
|
|
|
|
|
|
|
BOOL NSZombieEnabled = NO;
|
|
|
|
|
BOOL NSDeallocateZombies = NO;
|
|
|
|
|
|
|
|
|
|
@class NSZombie;
|
2011-02-12 15:44:00 +00:00
|
|
|
|
static Class zombieClass = Nil;
|
2011-02-11 10:00:00 +00:00
|
|
|
|
static NSMapTable *zombieMap = 0;
|
2002-03-27 09:55:57 +00:00
|
|
|
|
|
2011-05-28 14:51:40 +00:00
|
|
|
|
#if !GS_WITH_GC
|
2002-03-27 09:55:57 +00:00
|
|
|
|
static void GSMakeZombie(NSObject *o)
|
|
|
|
|
{
|
2011-02-11 10:00:00 +00:00
|
|
|
|
Class c;
|
2002-03-27 09:55:57 +00:00
|
|
|
|
|
2011-02-11 10:00:00 +00:00
|
|
|
|
c = object_getClass(o);
|
|
|
|
|
object_setClass(o, zombieClass);
|
2011-06-20 07:33:27 +00:00
|
|
|
|
if (0 != zombieMap)
|
2002-03-27 09:55:57 +00:00
|
|
|
|
{
|
2009-09-10 20:14:42 +00:00
|
|
|
|
[allocationLock lock];
|
2002-03-27 09:55:57 +00:00
|
|
|
|
NSMapInsert(zombieMap, (void*)o, (void*)c);
|
2009-09-10 20:14:42 +00:00
|
|
|
|
[allocationLock unlock];
|
2002-03-27 09:55:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2009-01-12 12:48:46 +00:00
|
|
|
|
#endif
|
2002-03-27 09:55:57 +00:00
|
|
|
|
|
|
|
|
|
static void GSLogZombie(id o, SEL sel)
|
|
|
|
|
{
|
|
|
|
|
Class c = 0;
|
|
|
|
|
|
2011-06-20 07:33:27 +00:00
|
|
|
|
if (0 != zombieMap)
|
2002-03-27 09:55:57 +00:00
|
|
|
|
{
|
2009-09-10 20:14:42 +00:00
|
|
|
|
[allocationLock lock];
|
2002-03-27 09:55:57 +00:00
|
|
|
|
c = NSMapGet(zombieMap, (void*)o);
|
2009-09-10 20:14:42 +00:00
|
|
|
|
[allocationLock unlock];
|
2002-03-27 09:55:57 +00:00
|
|
|
|
}
|
|
|
|
|
if (c == 0)
|
|
|
|
|
{
|
2011-01-07 09:52:20 +00:00
|
|
|
|
NSLog(@"*** -[??? %@]: message sent to deallocated instance %p",
|
|
|
|
|
NSStringFromSelector(sel), o);
|
2002-03-27 09:55:57 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2011-01-07 09:52:20 +00:00
|
|
|
|
NSLog(@"*** -[%@ %@]: message sent to deallocated instance %p",
|
|
|
|
|
c, NSStringFromSelector(sel), o);
|
2002-03-27 09:55:57 +00:00
|
|
|
|
}
|
2006-10-20 10:56:27 +00:00
|
|
|
|
if (GSPrivateEnvironmentFlag("CRASH_ON_ZOMBIE", NO) == YES)
|
2006-08-13 07:09:31 +00:00
|
|
|
|
{
|
|
|
|
|
abort();
|
|
|
|
|
}
|
2002-03-27 09:55:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-05-31 14:23:23 +00:00
|
|
|
|
|
1998-08-04 09:22:51 +00:00
|
|
|
|
/*
|
|
|
|
|
* Reference count and memory management
|
2009-03-06 11:01:42 +00:00
|
|
|
|
* Reference counts for object are stored
|
|
|
|
|
* with the object.
|
|
|
|
|
* The zone in which an object has been
|
|
|
|
|
* allocated is stored with the object.
|
1998-08-04 09:22:51 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2007-03-05 15:41:09 +00:00
|
|
|
|
/* Now, if we are on a platform where we know how to do atomic
|
|
|
|
|
* read, increment, and decrement, then we define the GSATOMICREAD
|
|
|
|
|
* macro and macros or functions to increment/decrement.
|
|
|
|
|
* The presence of the GSATOMICREAD macro is used later to determine
|
|
|
|
|
* whether to attempt atomic operations or to use locking for the
|
|
|
|
|
* retain/release mechanism.
|
|
|
|
|
* The GSAtomicIncrement() and GSAtomicDecrement() functions take a
|
|
|
|
|
* pointer to a 32bit integer as an argument, increment/decrement the
|
|
|
|
|
* value pointed to, and return the result.
|
|
|
|
|
*/
|
|
|
|
|
#ifdef GSATOMICREAD
|
|
|
|
|
#undef GSATOMICREAD
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-05-28 10:00:22 +00:00
|
|
|
|
|
2010-03-19 12:10:11 +00:00
|
|
|
|
#if defined(__MINGW__)
|
2008-11-17 13:45:32 +00:00
|
|
|
|
#ifndef _WIN64
|
2007-03-05 16:09:46 +00:00
|
|
|
|
#undef InterlockedIncrement
|
|
|
|
|
#undef InterlockedDecrement
|
2007-03-05 16:13:06 +00:00
|
|
|
|
LONG WINAPI InterlockedIncrement(LONG volatile *);
|
|
|
|
|
LONG WINAPI InterlockedDecrement(LONG volatile *);
|
2008-11-17 13:45:32 +00:00
|
|
|
|
#endif
|
2007-03-05 16:09:46 +00:00
|
|
|
|
|
2007-03-05 15:41:09 +00:00
|
|
|
|
/* Set up atomic read, increment and decrement for mswindows
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
typedef int32_t volatile *gsatomic_t;
|
|
|
|
|
|
|
|
|
|
#define GSATOMICREAD(X) (*(X))
|
|
|
|
|
|
2007-03-05 16:02:25 +00:00
|
|
|
|
#define GSAtomicIncrement(X) InterlockedIncrement((LONG volatile*)X)
|
|
|
|
|
#define GSAtomicDecrement(X) InterlockedDecrement((LONG volatile*)X)
|
2007-03-05 15:41:09 +00:00
|
|
|
|
|
|
|
|
|
|
2011-05-26 18:37:58 +00:00
|
|
|
|
#elif defined(__llvm__) || (defined(USE_ATOMIC_BUILTINS) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)))
|
2009-05-04 20:07:56 +00:00
|
|
|
|
/* Use the GCC atomic operations with recent GCC versions */
|
|
|
|
|
|
|
|
|
|
typedef int32_t volatile *gsatomic_t;
|
|
|
|
|
#define GSATOMICREAD(X) (*(X))
|
2011-05-25 22:18:39 +00:00
|
|
|
|
#define GSAtomicIncrement(X) __sync_add_and_fetch(X, 1)
|
|
|
|
|
#define GSAtomicDecrement(X) __sync_sub_and_fetch(X, 1)
|
2009-05-04 20:07:56 +00:00
|
|
|
|
|
|
|
|
|
|
2008-03-20 14:47:08 +00:00
|
|
|
|
#elif defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
|
2007-03-05 15:41:09 +00:00
|
|
|
|
/* Set up atomic read, increment and decrement for intel style linux
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
typedef int32_t volatile *gsatomic_t;
|
|
|
|
|
|
|
|
|
|
#define GSATOMICREAD(X) (*(X))
|
|
|
|
|
|
2011-05-25 15:53:17 +00:00
|
|
|
|
static __inline__ int
|
2007-03-05 15:41:09 +00:00
|
|
|
|
GSAtomicIncrement(gsatomic_t X)
|
|
|
|
|
{
|
2011-05-25 16:47:11 +00:00
|
|
|
|
register int tmp;
|
2011-05-25 09:20:42 +00:00
|
|
|
|
__asm__ __volatile__ (
|
2011-05-25 22:18:39 +00:00
|
|
|
|
"movl $1, %0\n"
|
2011-05-25 09:20:42 +00:00
|
|
|
|
"lock xaddl %0, %1"
|
|
|
|
|
:"=r" (tmp), "=m" (*X)
|
|
|
|
|
:"r" (tmp), "m" (*X)
|
|
|
|
|
:"memory" );
|
2011-05-25 22:18:39 +00:00
|
|
|
|
return tmp + 1;
|
2007-03-05 15:41:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-05-25 15:53:17 +00:00
|
|
|
|
static __inline__ int
|
2007-03-05 15:41:09 +00:00
|
|
|
|
GSAtomicDecrement(gsatomic_t X)
|
|
|
|
|
{
|
2011-05-25 16:47:11 +00:00
|
|
|
|
register int tmp;
|
2011-05-25 09:20:42 +00:00
|
|
|
|
__asm__ __volatile__ (
|
2011-05-25 22:18:39 +00:00
|
|
|
|
"movl $1, %0\n"
|
2011-05-26 18:37:58 +00:00
|
|
|
|
"negl %0\n"
|
2011-05-25 09:20:42 +00:00
|
|
|
|
"lock xaddl %0, %1"
|
|
|
|
|
:"=r" (tmp), "=m" (*X)
|
|
|
|
|
:"r" (tmp), "m" (*X)
|
|
|
|
|
:"memory" );
|
2011-05-25 22:18:39 +00:00
|
|
|
|
return tmp - 1;
|
2008-03-20 14:47:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-04-26 21:32:22 +00:00
|
|
|
|
#elif defined(__PPC__) || defined(__POWERPC__)
|
2008-03-20 14:47:08 +00:00
|
|
|
|
|
|
|
|
|
typedef int32_t volatile *gsatomic_t;
|
|
|
|
|
|
|
|
|
|
#define GSATOMICREAD(X) (*(X))
|
|
|
|
|
|
|
|
|
|
static __inline__ int
|
|
|
|
|
GSAtomicIncrement(gsatomic_t X)
|
|
|
|
|
{
|
|
|
|
|
int tmp;
|
|
|
|
|
__asm__ __volatile__ (
|
2010-04-26 21:32:22 +00:00
|
|
|
|
"0:"
|
2008-03-20 14:47:08 +00:00
|
|
|
|
"lwarx %0,0,%1 \n"
|
|
|
|
|
"addic %0,%0,1 \n"
|
|
|
|
|
"stwcx. %0,0,%1 \n"
|
2010-04-26 21:32:22 +00:00
|
|
|
|
"bne- 0b \n"
|
2008-03-20 14:47:08 +00:00
|
|
|
|
:"=&r" (tmp)
|
|
|
|
|
:"r" (X)
|
|
|
|
|
:"cc", "memory");
|
2011-05-25 22:18:39 +00:00
|
|
|
|
return tmp;
|
2008-03-20 14:47:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static __inline__ int
|
|
|
|
|
GSAtomicDecrement(gsatomic_t X)
|
|
|
|
|
{
|
|
|
|
|
int tmp;
|
|
|
|
|
__asm__ __volatile__ (
|
2010-04-26 21:32:22 +00:00
|
|
|
|
"0:"
|
2008-03-20 14:47:08 +00:00
|
|
|
|
"lwarx %0,0,%1 \n"
|
|
|
|
|
"addic %0,%0,-1 \n"
|
|
|
|
|
"stwcx. %0,0,%1 \n"
|
2010-04-26 21:32:22 +00:00
|
|
|
|
"bne- 0b \n"
|
2008-03-20 14:47:08 +00:00
|
|
|
|
:"=&r" (tmp)
|
|
|
|
|
:"r" (X)
|
|
|
|
|
:"cc", "memory");
|
2011-05-25 22:18:39 +00:00
|
|
|
|
return tmp;
|
2007-03-05 15:41:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-05-29 23:10:15 +00:00
|
|
|
|
#elif defined(__m68k__)
|
|
|
|
|
|
|
|
|
|
typedef int32_t volatile *gsatomic_t;
|
|
|
|
|
|
|
|
|
|
#define GSATOMICREAD(X) (*(X))
|
|
|
|
|
|
|
|
|
|
static __inline__ int
|
|
|
|
|
GSAtomicIncrement(gsatomic_t X)
|
|
|
|
|
{
|
|
|
|
|
__asm__ __volatile__ (
|
|
|
|
|
"addq%.l %#1, %0"
|
|
|
|
|
:"=m" (*X));
|
|
|
|
|
return *X;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static __inline__ int
|
|
|
|
|
GSAtomicDecrement(gsatomic_t X)
|
|
|
|
|
{
|
|
|
|
|
__asm__ __volatile__ (
|
|
|
|
|
"subq%.l %#1, %0"
|
|
|
|
|
:"=m" (*X));
|
|
|
|
|
return *X;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-23 00:03:21 +00:00
|
|
|
|
#elif defined(__mips__)
|
|
|
|
|
|
|
|
|
|
typedef int32_t volatile *gsatomic_t;
|
|
|
|
|
|
|
|
|
|
#define GSATOMICREAD(X) (*(X))
|
|
|
|
|
|
|
|
|
|
static __inline__ int
|
|
|
|
|
GSAtomicIncrement(gsatomic_t X)
|
|
|
|
|
{
|
|
|
|
|
int tmp;
|
|
|
|
|
|
|
|
|
|
__asm__ __volatile__ (
|
2011-01-06 12:48:29 +00:00
|
|
|
|
#if !defined(__mips64__)
|
2010-03-23 00:03:21 +00:00
|
|
|
|
" .set mips2 \n"
|
2011-01-06 12:48:29 +00:00
|
|
|
|
#endif
|
2010-03-23 00:03:21 +00:00
|
|
|
|
"0: ll %0, %1 \n"
|
|
|
|
|
" addiu %0, 1 \n"
|
|
|
|
|
" sc %0, %1 \n"
|
|
|
|
|
" beqz %0, 0b \n"
|
|
|
|
|
:"=&r" (tmp), "=m" (*X));
|
2011-05-25 22:18:39 +00:00
|
|
|
|
return tmp;
|
2010-03-23 00:03:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static __inline__ int
|
|
|
|
|
GSAtomicDecrement(gsatomic_t X)
|
|
|
|
|
{
|
|
|
|
|
int tmp;
|
|
|
|
|
|
|
|
|
|
__asm__ __volatile__ (
|
2011-01-06 12:48:29 +00:00
|
|
|
|
#if !defined(__mips64__)
|
2010-03-23 00:03:21 +00:00
|
|
|
|
" .set mips2 \n"
|
2011-01-06 12:48:29 +00:00
|
|
|
|
#endif
|
2010-03-23 00:03:21 +00:00
|
|
|
|
"0: ll %0, %1 \n"
|
|
|
|
|
" addiu %0, -1 \n"
|
|
|
|
|
" sc %0, %1 \n"
|
|
|
|
|
" beqz %0, 0b \n"
|
|
|
|
|
:"=&r" (tmp), "=m" (*X));
|
2011-05-25 22:18:39 +00:00
|
|
|
|
return tmp;
|
2010-03-23 00:03:21 +00:00
|
|
|
|
}
|
2007-03-05 15:41:09 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2009-03-06 11:01:42 +00:00
|
|
|
|
#if !defined(GSATOMICREAD)
|
2007-03-05 15:41:09 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Having just one allocationLock for all leads to lock contention
|
|
|
|
|
* if there are lots of threads doing lots of retain/release calls.
|
2009-03-06 11:01:42 +00:00
|
|
|
|
* To alleviate this, instead of a single
|
2007-03-05 15:41:09 +00:00
|
|
|
|
* allocationLock for all objects, we divide the object space into
|
|
|
|
|
* chunks, each with its own lock. The chunk is selected by shifting
|
|
|
|
|
* off the low-order ALIGNBITS of the object's pointer (these bits
|
|
|
|
|
* are presumably always zero) and take
|
|
|
|
|
* the low-order LOCKBITS of the result to index into a table of locks.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define LOCKBITS 5
|
|
|
|
|
#define LOCKCOUNT (1<<LOCKBITS)
|
|
|
|
|
#define LOCKMASK (LOCKCOUNT-1)
|
|
|
|
|
#define ALIGNBITS 3
|
|
|
|
|
|
2009-09-10 20:14:42 +00:00
|
|
|
|
static NSLock *allocationLocks[LOCKCOUNT] = { 0 };
|
2007-03-05 15:41:09 +00:00
|
|
|
|
|
2009-09-10 20:14:42 +00:00
|
|
|
|
static inline NSLock *GSAllocationLockForObject(id p)
|
2007-03-05 15:41:09 +00:00
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
|
NSUInteger i = ((((NSUInteger)(uintptr_t)p) >> ALIGNBITS) & LOCKMASK);
|
2007-03-05 15:41:09 +00:00
|
|
|
|
return allocationLocks[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
2001-12-28 03:40:03 +00:00
|
|
|
|
#ifdef ALIGN
|
|
|
|
|
#undef ALIGN
|
|
|
|
|
#endif
|
|
|
|
|
#define ALIGN __alignof__(double)
|
|
|
|
|
|
1998-08-04 09:22:51 +00:00
|
|
|
|
/*
|
|
|
|
|
* Define a structure to hold information that is held locally
|
|
|
|
|
* (before the start) in each object.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
*/
|
1998-08-13 20:45:32 +00:00
|
|
|
|
typedef struct obj_layout_unpadded {
|
|
|
|
|
NSZone *zone;
|
2011-07-04 11:31:28 +00:00
|
|
|
|
NSUInteger retained;
|
1998-08-13 20:45:32 +00:00
|
|
|
|
} unp;
|
1998-10-15 05:03:16 +00:00
|
|
|
|
#define UNP sizeof(unp)
|
1998-08-13 20:45:32 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Now do the REAL version - using the other version to determine
|
|
|
|
|
* what padding (if any) is required to get the alignment of the
|
|
|
|
|
* structure correct.
|
|
|
|
|
*/
|
1998-08-04 09:22:51 +00:00
|
|
|
|
struct obj_layout {
|
|
|
|
|
NSZone *zone;
|
2011-07-04 11:31:28 +00:00
|
|
|
|
NSUInteger retained;
|
1998-10-15 05:03:16 +00:00
|
|
|
|
char padding[ALIGN - ((UNP % ALIGN) ? (UNP % ALIGN) : ALIGN)];
|
1998-08-04 09:22:51 +00:00
|
|
|
|
};
|
|
|
|
|
typedef struct obj_layout *obj;
|
|
|
|
|
|
2011-05-28 14:51:40 +00:00
|
|
|
|
#ifdef __OBJC_GC__
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* If -base is compiled in GC mode, then we want to still support manual
|
|
|
|
|
* reference counting if we are linked with non-GC code.
|
|
|
|
|
*/
|
|
|
|
|
static BOOL GSDecrementExtraRefCountWasZero(id anObject);
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
|
NSDecrementExtraRefCountWasZero(id anObject)
|
|
|
|
|
{
|
|
|
|
|
if (!objc_collecting_enabled())
|
|
|
|
|
{
|
|
|
|
|
return GSDecrementExtraRefCountWasZero(anObject);
|
|
|
|
|
}
|
2011-05-28 15:28:24 +00:00
|
|
|
|
return NO;
|
2011-05-28 14:51:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-03-12 15:40:22 +00:00
|
|
|
|
|
2011-05-28 14:51:40 +00:00
|
|
|
|
static BOOL GSDecrementExtraRefCountWasZero(id anObject)
|
|
|
|
|
#else
|
2002-06-05 12:39:28 +00:00
|
|
|
|
/**
|
|
|
|
|
* Examines the extra reference count for the object and, if non-zero
|
|
|
|
|
* decrements it, otherwise leaves it unchanged.<br />
|
|
|
|
|
* Returns a flag to say whether the count was zero
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* (and hence whether the extra reference count was decremented).<br />
|
2002-06-05 12:39:28 +00:00
|
|
|
|
* This function is used by the [NSObject-release] method.
|
|
|
|
|
*/
|
2006-09-07 11:47:45 +00:00
|
|
|
|
BOOL
|
1998-08-04 09:22:51 +00:00
|
|
|
|
NSDecrementExtraRefCountWasZero(id anObject)
|
2011-05-28 14:51:40 +00:00
|
|
|
|
#endif
|
1998-08-04 09:22:51 +00:00
|
|
|
|
{
|
2011-05-28 14:51:40 +00:00
|
|
|
|
#if !GS_WITH_GC
|
2006-09-07 11:47:45 +00:00
|
|
|
|
if (double_release_check_enabled)
|
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
|
NSUInteger release_count;
|
|
|
|
|
NSUInteger retain_count = [anObject retainCount];
|
2006-09-07 11:47:45 +00:00
|
|
|
|
release_count = [autorelease_class autoreleaseCountForObject: anObject];
|
|
|
|
|
if (release_count >= retain_count)
|
|
|
|
|
[NSException raise: NSGenericException
|
|
|
|
|
format: @"Release would release object too many times."];
|
|
|
|
|
}
|
2002-03-27 09:55:57 +00:00
|
|
|
|
if (allocationLock != 0)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
2007-03-05 15:41:09 +00:00
|
|
|
|
#if defined(GSATOMICREAD)
|
2007-03-05 17:04:14 +00:00
|
|
|
|
int result;
|
2007-03-05 15:41:09 +00:00
|
|
|
|
|
2007-03-05 17:04:14 +00:00
|
|
|
|
result = GSAtomicDecrement((gsatomic_t)&(((obj)anObject)[-1].retained));
|
2007-03-05 15:41:09 +00:00
|
|
|
|
if (result < 0)
|
|
|
|
|
{
|
|
|
|
|
if (result != -1)
|
|
|
|
|
{
|
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
|
format: @"NSDecrementExtraRefCount() decremented too far"];
|
|
|
|
|
}
|
|
|
|
|
/* The counter has become negative so it must have been zero.
|
|
|
|
|
* We reset it and return YES ... in a correctly operating
|
|
|
|
|
* process we know we can safely reset back to zero without
|
|
|
|
|
* worrying about atomicity, since there can be no other
|
|
|
|
|
* thread accessing the object (or its reference count would
|
|
|
|
|
* have been greater than zero)
|
|
|
|
|
*/
|
|
|
|
|
(((obj)anObject)[-1].retained) = 0;
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
|
|
|
|
#else /* GSATOMICREAD */
|
2009-09-10 20:14:42 +00:00
|
|
|
|
NSLock *theLock = GSAllocationLockForObject(anObject);
|
2007-02-28 06:24:13 +00:00
|
|
|
|
|
2009-09-10 20:14:42 +00:00
|
|
|
|
[theLock lock];
|
2002-06-01 05:08:10 +00:00
|
|
|
|
if (((obj)anObject)[-1].retained == 0)
|
1999-12-10 00:59:40 +00:00
|
|
|
|
{
|
2009-09-10 20:14:42 +00:00
|
|
|
|
[theLock unlock];
|
1999-12-10 00:59:40 +00:00
|
|
|
|
return YES;
|
1999-12-13 12:14:01 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2002-06-01 05:08:10 +00:00
|
|
|
|
((obj)anObject)[-1].retained--;
|
2009-09-10 20:14:42 +00:00
|
|
|
|
[theLock unlock];
|
1999-12-10 00:59:40 +00:00
|
|
|
|
return NO;
|
|
|
|
|
}
|
2007-03-05 15:41:09 +00:00
|
|
|
|
#endif /* GSATOMICREAD */
|
1999-12-13 12:14:01 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2002-06-01 05:08:10 +00:00
|
|
|
|
if (((obj)anObject)[-1].retained == 0)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2002-06-01 05:08:10 +00:00
|
|
|
|
((obj)anObject)[-1].retained--;
|
1999-12-13 12:14:01 +00:00
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-03-06 11:01:42 +00:00
|
|
|
|
#endif /* !GS_WITH_GC */
|
2007-03-05 16:02:25 +00:00
|
|
|
|
return NO;
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
|
2002-06-05 12:39:28 +00:00
|
|
|
|
/**
|
|
|
|
|
* Return the extra reference count of anObject (a value in the range
|
|
|
|
|
* from 0 to the maximum unsigned integer value minus one).<br />
|
|
|
|
|
* The retain count for an object is this value plus one.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
inline NSUInteger
|
2002-06-05 12:39:28 +00:00
|
|
|
|
NSExtraRefCount(id anObject)
|
1997-09-01 21:59:51 +00:00
|
|
|
|
{
|
2011-05-28 14:51:40 +00:00
|
|
|
|
#ifdef __OBJC_GC__
|
|
|
|
|
if (objc_collecting_enabled())
|
|
|
|
|
{
|
|
|
|
|
return UINT_MAX-1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#if GS_WITH_GC
|
2002-06-05 12:39:28 +00:00
|
|
|
|
return UINT_MAX - 1;
|
|
|
|
|
#else /* GS_WITH_GC */
|
|
|
|
|
return ((obj)anObject)[-1].retained;
|
2009-03-06 11:01:42 +00:00
|
|
|
|
#endif /* GS_WITH_GC */
|
1997-09-01 21:59:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-05-28 14:51:40 +00:00
|
|
|
|
#ifdef __OBJC_GC__
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* If -base is compiled in GC mode, then we want to still support manual
|
|
|
|
|
* reference counting if we are linked with non-GC code.
|
|
|
|
|
*/
|
|
|
|
|
static void GSIncrementExtraRefCount(id anObject);
|
|
|
|
|
|
|
|
|
|
inline void NSIncrementExtraRefCount(id anObject)
|
|
|
|
|
{
|
|
|
|
|
if (!objc_collecting_enabled())
|
|
|
|
|
{
|
|
|
|
|
GSIncrementExtraRefCount(anObject);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void GSIncrementExtraRefCount(id anObject)
|
|
|
|
|
#else
|
2002-06-05 12:39:28 +00:00
|
|
|
|
/**
|
|
|
|
|
* Increments the extra reference count for anObject.<br />
|
|
|
|
|
* The GNUstep version raises an exception if the reference count
|
|
|
|
|
* would be incremented to too large a value.<br />
|
|
|
|
|
* This is used by the [NSObject-retain] method.
|
|
|
|
|
*/
|
|
|
|
|
inline void
|
|
|
|
|
NSIncrementExtraRefCount(id anObject)
|
2011-05-28 14:51:40 +00:00
|
|
|
|
#endif
|
2002-06-05 12:39:28 +00:00
|
|
|
|
{
|
2011-05-24 14:43:27 +00:00
|
|
|
|
#if GS_WITH_GC || __OBJC_GC__
|
2002-06-05 12:39:28 +00:00
|
|
|
|
return;
|
|
|
|
|
#else /* GS_WITH_GC */
|
|
|
|
|
if (allocationLock != 0)
|
|
|
|
|
{
|
2007-03-05 15:41:09 +00:00
|
|
|
|
#if defined(GSATOMICREAD)
|
|
|
|
|
/* I've seen comments saying that some platforms only support up to
|
|
|
|
|
* 24 bits in atomic locking, so raise an exception if we try to
|
|
|
|
|
* go beyond 0xfffffe.
|
|
|
|
|
*/
|
2007-03-05 17:04:14 +00:00
|
|
|
|
if (GSAtomicIncrement((gsatomic_t)&(((obj)anObject)[-1].retained))
|
|
|
|
|
> 0xfffffe)
|
2007-03-05 15:41:09 +00:00
|
|
|
|
{
|
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
|
format: @"NSIncrementExtraRefCount() asked to increment too far"];
|
|
|
|
|
}
|
|
|
|
|
#else /* GSATOMICREAD */
|
2009-09-10 20:14:42 +00:00
|
|
|
|
NSLock *theLock = GSAllocationLockForObject(anObject);
|
2007-02-28 06:24:13 +00:00
|
|
|
|
|
2009-09-10 20:14:42 +00:00
|
|
|
|
[theLock lock];
|
2002-06-05 12:39:28 +00:00
|
|
|
|
if (((obj)anObject)[-1].retained == UINT_MAX - 1)
|
|
|
|
|
{
|
2009-10-20 05:25:04 +00:00
|
|
|
|
[theLock unlock];
|
2002-06-05 12:39:28 +00:00
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
|
format: @"NSIncrementExtraRefCount() asked to increment too far"];
|
|
|
|
|
}
|
|
|
|
|
((obj)anObject)[-1].retained++;
|
2009-10-20 05:25:04 +00:00
|
|
|
|
[theLock unlock];
|
2007-03-05 15:41:09 +00:00
|
|
|
|
#endif /* GSATOMICREAD */
|
2002-06-05 12:39:28 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (((obj)anObject)[-1].retained == UINT_MAX - 1)
|
|
|
|
|
{
|
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
|
format: @"NSIncrementExtraRefCount() asked to increment too far"];
|
|
|
|
|
}
|
|
|
|
|
((obj)anObject)[-1].retained++;
|
|
|
|
|
}
|
2007-03-05 15:41:09 +00:00
|
|
|
|
#endif /* GS_WITH_GC */
|
2002-06-05 12:39:28 +00:00
|
|
|
|
}
|
1999-01-28 17:21:03 +00:00
|
|
|
|
|
2009-04-15 08:03:19 +00:00
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
#define AADD(c, o) GSDebugAllocationAdd(c, o)
|
|
|
|
|
#define AREM(c, o) GSDebugAllocationRemove(c, o)
|
|
|
|
|
#else
|
2011-05-26 18:37:58 +00:00
|
|
|
|
#define AADD(c, o)
|
|
|
|
|
#define AREM(c, o)
|
2009-04-15 08:03:19 +00:00
|
|
|
|
#endif
|
1998-08-04 09:22:51 +00:00
|
|
|
|
|
2011-04-05 12:13:12 +00:00
|
|
|
|
static SEL cxx_construct, cxx_destruct;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calls the C++ constructors for this object, starting with the ones declared
|
|
|
|
|
* in aClass. The compiler generates two methods on Objective-C++ classes that
|
|
|
|
|
* static instances of C++ classes as ivars. These are -.cxx_construct and
|
|
|
|
|
* -.cxx_destruct. The -.cxx_construct methods must be called in order from
|
|
|
|
|
* the root class to all subclasses, to ensure that subclass ivars are
|
|
|
|
|
* initialised after superclass ones. This must be done in reverse for
|
2011-05-26 18:37:58 +00:00
|
|
|
|
* destruction.
|
2011-04-05 12:13:12 +00:00
|
|
|
|
*
|
|
|
|
|
* This function first calls itself recursively on the superclass, to get the
|
|
|
|
|
* IMP for the constructor function in the superclass. It then compares the
|
|
|
|
|
* construct method for this class with the one that's already been called,
|
|
|
|
|
* and calls it if it's new.
|
|
|
|
|
*/
|
|
|
|
|
static IMP
|
|
|
|
|
callCXXConstructors(Class aClass, id anObject)
|
|
|
|
|
{
|
|
|
|
|
IMP constructor = 0;
|
|
|
|
|
|
|
|
|
|
if (class_respondsToSelector(aClass, cxx_construct))
|
|
|
|
|
{
|
|
|
|
|
IMP calledConstructor =
|
|
|
|
|
callCXXConstructors(class_getSuperclass(aClass), anObject);
|
|
|
|
|
constructor = class_getMethodImplementation(aClass, cxx_construct);
|
|
|
|
|
if (calledConstructor != constructor)
|
|
|
|
|
{
|
|
|
|
|
constructor(anObject, cxx_construct);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return constructor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1998-08-04 09:22:51 +00:00
|
|
|
|
/*
|
|
|
|
|
* Now do conditional compilation of memory allocation functions
|
|
|
|
|
* depending on what information (if any) we are storing before
|
|
|
|
|
* the start of each object.
|
|
|
|
|
*/
|
2011-05-28 15:28:24 +00:00
|
|
|
|
#if GS_WITH_GC
|
1999-01-28 17:21:03 +00:00
|
|
|
|
|
|
|
|
|
inline NSZone *
|
2000-10-31 16:17:33 +00:00
|
|
|
|
GSObjCZone(NSObject *object)
|
1999-01-28 17:21:03 +00:00
|
|
|
|
{
|
2010-03-05 09:30:18 +00:00
|
|
|
|
GSOnceFLog(@"GSObjCZone() is deprecated ... use -zone instead");
|
2009-02-11 10:11:33 +00:00
|
|
|
|
/* MacOS-X 10.5 seems to return the default malloc zone if GC is enabled.
|
2009-01-19 11:00:33 +00:00
|
|
|
|
*/
|
2009-02-11 10:11:33 +00:00
|
|
|
|
return NSDefaultMallocZone();
|
1999-01-28 17:21:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
GSFinalize(void* object, void* data)
|
|
|
|
|
{
|
2009-01-12 18:36:37 +00:00
|
|
|
|
[(id)object finalize];
|
2011-02-20 12:28:12 +00:00
|
|
|
|
AREM(object_getClass((id)object), (id)object);
|
2011-02-27 16:14:26 +00:00
|
|
|
|
object_setClass((id)object, (Class)(void*)0xdeadface);
|
1999-01-28 17:21:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-04-15 08:03:19 +00:00
|
|
|
|
static BOOL
|
|
|
|
|
GSIsFinalizable(Class c)
|
|
|
|
|
{
|
2011-04-03 04:25:52 +00:00
|
|
|
|
if (class_getMethodImplementation(c, finalize_sel) != finalize_imp
|
|
|
|
|
&& class_respondsToSelector(c, finalize_sel))
|
2009-04-15 08:03:19 +00:00
|
|
|
|
return YES;
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-13 17:33:23 +00:00
|
|
|
|
inline id
|
2009-02-23 20:42:32 +00:00
|
|
|
|
NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone)
|
1999-01-28 17:21:03 +00:00
|
|
|
|
{
|
2002-05-03 10:10:38 +00:00
|
|
|
|
id new;
|
|
|
|
|
int size;
|
2009-01-19 11:00:33 +00:00
|
|
|
|
GC_descr gc_type;
|
1999-09-28 10:25:42 +00:00
|
|
|
|
|
A huge blob of changes to make -base build with libobjc2, without using the old libobjc2 headers.
Most of these changes involve simply removing direct manipulation of any runtime structures and replacing them with runtime function calls. For example class->name becomes class_getName(class) and so on.
libobjc2, like the Apple runtime, the NeXT runtime, and every version of the Objective-C spec, calls the class pointer in id isa. A few files now have #define class_pointer isa at the top. This line replaces class_pointer in the old GNU libobjc headers with isa so either class_pointer or isa can be used for accessing the class of an object. Note: object_getClass() should be used in most cases because, in some future version of the runtime, this will skip things like lock classes and other hidden classes (e.g. KVO classes).
All of the old forwarding stuff has been removed. Most of this stuff followed convoluted code paths that ended with an exception. A few simply broke in exciting ways. Hopefully no one has used them for the last ten years or so, but we can bring them back with some #ifndef stuff if they're really needed by anyone.
There is currently a bug in configure, which prevents dladdr() from being detected, so you need to manually tweak config.h to build - I have not fixed the fall-back code in objc-load.m to work with libobjc2, I just added a new version that uses the loader's functionality directly.
Although -base now builds, it builds with a lot of warnings. <string.h> is missing from a lot of files, so memcpy() and strlen() generate implicit function declaration warnings.
Additionally, libobjc2 does still provide the sel_{get,register}_*() functions, but they're wrappers around the newer API ones. These are deprecated and are not exposed in the headers. Although they work, we should be replacing them with the libobjc2 versions as soon as possible.
This incorporates a patch by Eric.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31265 72102866-910b-0410-8b05-ffd578937521
2010-09-09 15:06:09 +00:00
|
|
|
|
NSCAssert((!class_isMetaClass(aClass)), @"Bad class for new object");
|
2009-01-19 11:00:33 +00:00
|
|
|
|
gc_type = (GC_descr)aClass->gc_object_type;
|
2010-02-25 18:49:31 +00:00
|
|
|
|
size = class_getInstanceSize(aClass) + extraBytes;
|
2009-01-12 18:36:37 +00:00
|
|
|
|
if (size % sizeof(void*) != 0)
|
|
|
|
|
{
|
|
|
|
|
/* Size must be a multiple of pointer size for the garbage collector
|
|
|
|
|
* to be able to allocate explicitly typed memory.
|
|
|
|
|
*/
|
|
|
|
|
size += sizeof(void*) - size % sizeof(void*);
|
|
|
|
|
}
|
2009-01-19 11:00:33 +00:00
|
|
|
|
|
|
|
|
|
if (gc_type == 0)
|
1999-09-29 14:13:52 +00:00
|
|
|
|
{
|
2009-01-12 18:36:37 +00:00
|
|
|
|
new = NSZoneCalloc(zone, 1, size);
|
2009-01-19 11:00:33 +00:00
|
|
|
|
NSLog(@"No garbage collection information for '%s'",
|
2010-02-22 10:13:20 +00:00
|
|
|
|
class_getName(aClass));
|
1999-09-29 14:13:52 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-01-19 11:00:33 +00:00
|
|
|
|
new = GC_calloc_explicitly_typed(1, size, gc_type);
|
1999-09-29 14:13:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-01-28 17:21:03 +00:00
|
|
|
|
if (new != nil)
|
|
|
|
|
{
|
2011-02-20 12:28:12 +00:00
|
|
|
|
object_setClass(new, aClass);
|
2011-04-05 12:13:12 +00:00
|
|
|
|
|
|
|
|
|
/* Don't bother doing this in a thread-safe way, because
|
|
|
|
|
* the cost of locking will be a lot more than the cost
|
|
|
|
|
* of doing the same call in two threads.
|
|
|
|
|
* The returned selector will persist and the runtime will
|
|
|
|
|
* ensure that both calls return the same selector, so we
|
|
|
|
|
* don't need to bother doing it ourselves.
|
|
|
|
|
*/
|
|
|
|
|
if (0 == cxx_construct)
|
|
|
|
|
{
|
|
|
|
|
cxx_construct = sel_registerName(".cxx_construct");
|
|
|
|
|
cxx_destruct = sel_registerName(".cxx_destruct");
|
|
|
|
|
}
|
|
|
|
|
callCXXConstructors(aClass, new);
|
|
|
|
|
|
|
|
|
|
/* We only need to finalize this object if it implements its a
|
|
|
|
|
* -finalize method or has C++ destructors.
|
|
|
|
|
*/
|
|
|
|
|
if (GSIsFinalizable(aClass)
|
2011-04-14 12:31:51 +00:00
|
|
|
|
|| class_respondsToSelector(aClass, cxx_destruct))
|
1999-09-28 10:25:42 +00:00
|
|
|
|
{
|
2009-04-15 08:03:19 +00:00
|
|
|
|
/* We only do allocation counting for objects that can be
|
|
|
|
|
* finalised - for other objects we have no way of decrementing
|
|
|
|
|
* the count when the object is collected.
|
1999-09-28 10:25:42 +00:00
|
|
|
|
*/
|
2009-04-15 08:03:19 +00:00
|
|
|
|
AADD(aClass, new);
|
1999-09-28 10:25:42 +00:00
|
|
|
|
GC_REGISTER_FINALIZER (new, GSFinalize, NULL, NULL, NULL);
|
|
|
|
|
}
|
1999-01-28 17:21:03 +00:00
|
|
|
|
}
|
|
|
|
|
return new;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline void
|
2010-02-13 17:33:23 +00:00
|
|
|
|
NSDeallocateObject(id anObject)
|
1999-01-28 17:21:03 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else /* GS_WITH_GC */
|
|
|
|
|
|
2011-05-28 15:28:24 +00:00
|
|
|
|
#if !__OBJC_GC__
|
1998-10-15 05:03:16 +00:00
|
|
|
|
inline NSZone *
|
2000-10-31 16:17:33 +00:00
|
|
|
|
GSObjCZone(NSObject *object)
|
1998-10-15 05:03:16 +00:00
|
|
|
|
{
|
2010-03-05 09:30:18 +00:00
|
|
|
|
GSOnceFLog(@"GSObjCZone() is deprecated ... use -zone instead");
|
2010-02-22 10:13:20 +00:00
|
|
|
|
if (object_getClass(object) == NSConstantStringClass)
|
1999-01-28 17:21:03 +00:00
|
|
|
|
return NSDefaultMallocZone();
|
|
|
|
|
return ((obj)object)[-1].zone;
|
1998-10-15 05:03:16 +00:00
|
|
|
|
}
|
2011-05-28 15:28:24 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if __OBJC_GC__
|
|
|
|
|
inline NSZone *
|
|
|
|
|
GSObjCZone(NSObject *object)
|
|
|
|
|
{
|
|
|
|
|
return NSDefaultMallocZone();
|
|
|
|
|
}
|
|
|
|
|
static inline id
|
|
|
|
|
GSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone);
|
1998-10-15 05:03:16 +00:00
|
|
|
|
|
2011-05-28 15:28:24 +00:00
|
|
|
|
inline id
|
|
|
|
|
NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone)
|
|
|
|
|
{
|
|
|
|
|
if (!objc_collecting_enabled())
|
|
|
|
|
{
|
2011-07-04 21:23:26 +00:00
|
|
|
|
GSAllocateObject(aClass, extraBytes, zone);
|
2011-05-28 15:28:24 +00:00
|
|
|
|
}
|
|
|
|
|
id new = class_createInstance(aClass, extraBytes);
|
|
|
|
|
if (0 == cxx_construct)
|
|
|
|
|
{
|
|
|
|
|
cxx_construct = sel_registerName(".cxx_construct");
|
|
|
|
|
cxx_destruct = sel_registerName(".cxx_destruct");
|
|
|
|
|
}
|
|
|
|
|
return new;
|
|
|
|
|
}
|
|
|
|
|
inline id
|
|
|
|
|
GSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone)
|
|
|
|
|
#else
|
2010-02-13 17:33:23 +00:00
|
|
|
|
inline id
|
2009-02-23 20:42:32 +00:00
|
|
|
|
NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone)
|
2011-05-28 15:28:24 +00:00
|
|
|
|
#endif
|
1998-08-04 09:22:51 +00:00
|
|
|
|
{
|
2002-05-03 10:10:38 +00:00
|
|
|
|
id new;
|
|
|
|
|
int size;
|
|
|
|
|
|
A huge blob of changes to make -base build with libobjc2, without using the old libobjc2 headers.
Most of these changes involve simply removing direct manipulation of any runtime structures and replacing them with runtime function calls. For example class->name becomes class_getName(class) and so on.
libobjc2, like the Apple runtime, the NeXT runtime, and every version of the Objective-C spec, calls the class pointer in id isa. A few files now have #define class_pointer isa at the top. This line replaces class_pointer in the old GNU libobjc headers with isa so either class_pointer or isa can be used for accessing the class of an object. Note: object_getClass() should be used in most cases because, in some future version of the runtime, this will skip things like lock classes and other hidden classes (e.g. KVO classes).
All of the old forwarding stuff has been removed. Most of this stuff followed convoluted code paths that ended with an exception. A few simply broke in exciting ways. Hopefully no one has used them for the last ten years or so, but we can bring them back with some #ifndef stuff if they're really needed by anyone.
There is currently a bug in configure, which prevents dladdr() from being detected, so you need to manually tweak config.h to build - I have not fixed the fall-back code in objc-load.m to work with libobjc2, I just added a new version that uses the loader's functionality directly.
Although -base now builds, it builds with a lot of warnings. <string.h> is missing from a lot of files, so memcpy() and strlen() generate implicit function declaration warnings.
Additionally, libobjc2 does still provide the sel_{get,register}_*() functions, but they're wrappers around the newer API ones. These are deprecated and are not exposed in the headers. Although they work, we should be replacing them with the libobjc2 versions as soon as possible.
This incorporates a patch by Eric.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31265 72102866-910b-0410-8b05-ffd578937521
2010-09-09 15:06:09 +00:00
|
|
|
|
NSCAssert((!class_isMetaClass(aClass)), @"Bad class for new object");
|
2010-02-25 18:49:31 +00:00
|
|
|
|
size = class_getInstanceSize(aClass) + extraBytes + sizeof(struct obj_layout);
|
2002-05-03 10:10:38 +00:00
|
|
|
|
if (zone == 0)
|
1998-08-04 09:22:51 +00:00
|
|
|
|
{
|
2002-05-03 10:10:38 +00:00
|
|
|
|
zone = NSDefaultMallocZone();
|
1998-08-04 09:22:51 +00:00
|
|
|
|
}
|
2002-05-03 10:10:38 +00:00
|
|
|
|
new = NSZoneMalloc(zone, size);
|
1998-08-04 09:22:51 +00:00
|
|
|
|
if (new != nil)
|
|
|
|
|
{
|
|
|
|
|
memset (new, 0, size);
|
|
|
|
|
((obj)new)->zone = zone;
|
|
|
|
|
new = (id)&((obj)new)[1];
|
2011-02-20 12:28:12 +00:00
|
|
|
|
object_setClass(new, aClass);
|
2009-04-15 08:03:19 +00:00
|
|
|
|
AADD(aClass, new);
|
1998-10-15 05:03:16 +00:00
|
|
|
|
}
|
2011-04-05 12:13:12 +00:00
|
|
|
|
|
|
|
|
|
/* Don't bother doing this in a thread-safe way, because the cost of locking
|
|
|
|
|
* will be a lot more than the cost of doing the same call in two threads.
|
|
|
|
|
* The returned selector will persist and the runtime will ensure that both
|
|
|
|
|
* calls return the same selector, so we don't need to bother doing it
|
|
|
|
|
* ourselves.
|
|
|
|
|
*/
|
2011-03-17 15:02:52 +00:00
|
|
|
|
if (0 == cxx_construct)
|
|
|
|
|
{
|
|
|
|
|
cxx_construct = sel_registerName(".cxx_construct");
|
|
|
|
|
cxx_destruct = sel_registerName(".cxx_destruct");
|
|
|
|
|
}
|
|
|
|
|
callCXXConstructors(aClass, new);
|
2011-04-05 12:13:12 +00:00
|
|
|
|
|
1998-08-04 09:22:51 +00:00
|
|
|
|
return new;
|
|
|
|
|
}
|
2011-05-28 15:28:24 +00:00
|
|
|
|
#if __OBJC_GC__
|
|
|
|
|
static void GSDeallocateObject(id anObject);
|
1998-08-04 09:22:51 +00:00
|
|
|
|
|
2011-05-28 15:28:24 +00:00
|
|
|
|
inline void NSDeallocateObject(id anObject)
|
|
|
|
|
{
|
|
|
|
|
if (!objc_collecting_enabled())
|
|
|
|
|
{
|
|
|
|
|
GSDeallocateObject(anObject);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void GSDeallocateObject(id anObject)
|
|
|
|
|
#else
|
1998-11-12 08:02:48 +00:00
|
|
|
|
inline void
|
2010-02-13 17:33:23 +00:00
|
|
|
|
NSDeallocateObject(id anObject)
|
2011-05-28 15:28:24 +00:00
|
|
|
|
#endif
|
1998-08-04 09:22:51 +00:00
|
|
|
|
{
|
2011-03-17 15:02:52 +00:00
|
|
|
|
Class aClass = object_getClass(anObject);
|
2011-04-05 12:13:12 +00:00
|
|
|
|
|
|
|
|
|
if ((anObject != nil) && !class_isMetaClass(aClass))
|
1998-08-04 09:22:51 +00:00
|
|
|
|
{
|
|
|
|
|
obj o = &((obj)anObject)[-1];
|
2010-03-05 09:30:18 +00:00
|
|
|
|
NSZone *z = o->zone;
|
1998-08-04 09:22:51 +00:00
|
|
|
|
|
2011-04-05 12:13:12 +00:00
|
|
|
|
/* Call the default finalizer to handle C++ destructors.
|
|
|
|
|
*/
|
|
|
|
|
(*finalize_imp)(anObject, finalize_sel);
|
|
|
|
|
|
|
|
|
|
AREM(aClass, (id)anObject);
|
2002-03-27 09:55:57 +00:00
|
|
|
|
if (NSZombieEnabled == YES)
|
|
|
|
|
{
|
|
|
|
|
GSMakeZombie(anObject);
|
|
|
|
|
if (NSDeallocateZombies == YES)
|
|
|
|
|
{
|
|
|
|
|
NSZoneFree(z, o);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2011-02-20 12:28:12 +00:00
|
|
|
|
object_setClass((id)anObject, (Class)(void*)0xdeadface);
|
2002-03-27 09:55:57 +00:00
|
|
|
|
NSZoneFree(z, o);
|
|
|
|
|
}
|
1998-08-04 09:22:51 +00:00
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
1999-01-28 17:21:03 +00:00
|
|
|
|
#endif /* GS_WITH_GC */
|
|
|
|
|
|
1998-08-04 09:22:51 +00:00
|
|
|
|
BOOL
|
|
|
|
|
NSShouldRetainWithZone (NSObject *anObject, NSZone *requestedZone)
|
|
|
|
|
{
|
2011-05-24 14:43:27 +00:00
|
|
|
|
#if GS_WITH_GC || __OBJC_GC__
|
2011-05-28 15:28:24 +00:00
|
|
|
|
// If we're running in hybrid mode, we disable all of the clever zone stuff
|
|
|
|
|
// for non-GC code, so this is always true if we're compiled for GC, even if
|
|
|
|
|
// we're compiled for GC but not using GC.
|
1999-01-28 17:21:03 +00:00
|
|
|
|
return YES;
|
|
|
|
|
#else
|
|
|
|
|
return (!requestedZone || requestedZone == NSDefaultMallocZone()
|
2010-03-05 09:30:18 +00:00
|
|
|
|
|| [anObject zone] == requestedZone);
|
1999-01-28 17:21:03 +00:00
|
|
|
|
#endif
|
1998-08-04 09:22:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1996-07-15 18:41:44 +00:00
|
|
|
|
|
2002-08-20 10:22:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* <p>
|
|
|
|
|
* <code>NSObject</code> is the root class (a root class is
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* a class with no superclass) of the GNUstep base library
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* class hierarchy, so all classes normally inherit from
|
|
|
|
|
* <code>NSObject</code>. There is an exception though:
|
|
|
|
|
* <code>NSProxy</code> (which is used for remote messaging)
|
|
|
|
|
* does not inherit from <code>NSObject</code>.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* Unless you are really sure of what you are doing, all
|
|
|
|
|
* your own classes should inherit (directly or indirectly)
|
|
|
|
|
* from <code>NSObject</code> (or in special cases from
|
|
|
|
|
* <code>NSProxy</code>). <code>NSObject</code> provides
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* the basic common functionality shared by all GNUstep
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* classes and objects.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* The essential methods which must be implemented by all
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* classes for their instances to be usable within GNUstep
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* are declared in a separate protocol, which is the
|
|
|
|
|
* <code>NSObject</code> protocol. Both
|
|
|
|
|
* <code>NSObject</code> and <code>NSProxy</code> conform to
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* this protocol, which means all objects in a GNUstep
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* application will conform to this protocol (btw, if you
|
|
|
|
|
* don't find a method of <code>NSObject</code> you are
|
|
|
|
|
* looking for in this documentation, make sure you also
|
|
|
|
|
* look into the documentation for the <code>NSObject</code>
|
|
|
|
|
* protocol).
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* Theoretically, in special cases you might need to
|
|
|
|
|
* implement a new root class. If you do, you need to make
|
|
|
|
|
* sure that your root class conforms (at least) to the
|
|
|
|
|
* <code>NSObject</code> protocol, otherwise it will not
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* interact correctly with the GNUstep framework. Said
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* that, I must note that I have never seen a case in which
|
|
|
|
|
* a new root class is needed.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* <code>NSObject</code> is a root class, which implies that
|
|
|
|
|
* instance methods of <code>NSObject</code> are treated in
|
|
|
|
|
* a special way by the Objective-C runtime. This is an
|
|
|
|
|
* exception to the normal way messaging works with class
|
|
|
|
|
* and instance methods: if the Objective-C runtime can't
|
|
|
|
|
* find a class method for a class object, as a last resort
|
|
|
|
|
* it looks for an instance method of the root class with
|
|
|
|
|
* the same name, and executes it if it finds it. This
|
|
|
|
|
* means that instance methods of the root class (such as
|
|
|
|
|
* <code>NSObject</code>) can be performed by class objects
|
|
|
|
|
* which inherit from that root class ! This can only
|
|
|
|
|
* happen if the class doesn't have a class method with the
|
|
|
|
|
* same name, otherwise that method - of course - takes the
|
|
|
|
|
* precedence. Because of this exception,
|
|
|
|
|
* <code>NSObject</code>'s instance methods are written in
|
|
|
|
|
* such a way that they work both on <code>NSObject</code>'s
|
|
|
|
|
* instances and on class objects.
|
|
|
|
|
* </p>
|
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
@implementation NSObject
|
2011-07-04 11:31:28 +00:00
|
|
|
|
- (void)_ARCCompliantRetainRelease {}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
|
2002-09-12 09:09:54 +00:00
|
|
|
|
+ (void) _becomeMultiThreaded: (NSNotification *)aNotification
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
2002-03-27 09:55:57 +00:00
|
|
|
|
if (allocationLock == 0)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
2009-03-06 11:01:42 +00:00
|
|
|
|
#if !defined(GSATOMICREAD)
|
2009-02-23 20:42:32 +00:00
|
|
|
|
NSUInteger i;
|
2007-02-28 06:24:13 +00:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < LOCKCOUNT; i++)
|
|
|
|
|
{
|
2009-09-10 20:14:42 +00:00
|
|
|
|
allocationLocks[i] = [NSLock new];
|
2007-02-28 06:24:13 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
2009-09-10 20:14:42 +00:00
|
|
|
|
allocationLock = [NSLock new];
|
1999-12-13 12:14:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-10 17:12:47 +00:00
|
|
|
|
#if GS_WITH_GC
|
2009-03-24 10:53:38 +00:00
|
|
|
|
/* Function to log Boehm GC warnings
|
|
|
|
|
* NB. This must not allocate any collectable memory as it may result
|
|
|
|
|
* in a deadlock in the garbage collecting library.
|
2009-03-10 17:12:47 +00:00
|
|
|
|
*/
|
|
|
|
|
static void
|
2009-04-10 08:25:03 +00:00
|
|
|
|
GSGarbageCollectorLog(char *msg, GC_word arg)
|
2009-03-10 17:12:47 +00:00
|
|
|
|
{
|
|
|
|
|
char buf[strlen(msg)+1024];
|
2011-03-07 15:34:06 +00:00
|
|
|
|
snprintf(buf, sizeof(buf), msg, (unsigned long)arg);
|
2009-03-24 10:53:38 +00:00
|
|
|
|
fprintf(stderr, "Garbage collector: %s", buf);
|
2009-03-10 17:12:47 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2009-12-20 16:59:41 +00:00
|
|
|
|
/**
|
|
|
|
|
* Semi-private function in libobjc2 that initialises the classes used for
|
|
|
|
|
* blocks.
|
|
|
|
|
*/
|
2011-05-26 18:37:58 +00:00
|
|
|
|
extern BOOL
|
2011-03-13 09:41:20 +00:00
|
|
|
|
objc_create_block_classes_as_subclasses_of(Class super);
|
2009-12-20 16:59:41 +00:00
|
|
|
|
|
2011-06-29 13:13:15 +00:00
|
|
|
|
#ifdef OBJC_CAP_ARC
|
|
|
|
|
static id gs_weak_load(id obj)
|
|
|
|
|
{
|
2011-07-07 12:29:54 +00:00
|
|
|
|
return [obj retainCount] > 0 ? obj : nil;
|
2011-06-29 13:13:15 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-03-13 09:38:37 +00:00
|
|
|
|
+ (void) load
|
2009-12-20 16:59:41 +00:00
|
|
|
|
{
|
2011-06-29 13:13:15 +00:00
|
|
|
|
#ifdef OBJC_CAP_ARC
|
|
|
|
|
_objc_weak_load = gs_weak_load;
|
|
|
|
|
#endif
|
2011-03-13 09:38:37 +00:00
|
|
|
|
objc_create_block_classes_as_subclasses_of(self);
|
2009-12-20 16:59:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
1994-11-08 16:44:01 +00:00
|
|
|
|
+ (void) initialize
|
|
|
|
|
{
|
1995-03-12 15:40:22 +00:00
|
|
|
|
if (self == [NSObject class])
|
|
|
|
|
{
|
2009-03-08 14:29:06 +00:00
|
|
|
|
#if GS_WITH_GC
|
|
|
|
|
/* Make sure that the garbage collection library is initialised.
|
|
|
|
|
* This is not necessary on most platforms, but is good practice.
|
|
|
|
|
*/
|
|
|
|
|
GC_init();
|
2009-04-10 08:25:03 +00:00
|
|
|
|
GC_set_warn_proc(GSGarbageCollectorLog);
|
2009-03-08 14:29:06 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2010-03-19 12:10:11 +00:00
|
|
|
|
#ifdef __MINGW__
|
2009-03-08 14:29:06 +00:00
|
|
|
|
{
|
|
|
|
|
// See libgnustep-base-entry.m
|
2011-05-26 18:37:58 +00:00
|
|
|
|
extern void gnustep_base_socket_init(void);
|
|
|
|
|
gnustep_base_socket_init();
|
2009-03-08 14:29:06 +00:00
|
|
|
|
}
|
2010-03-19 12:10:11 +00:00
|
|
|
|
#else /* __MINGW__ */
|
2009-01-12 18:36:37 +00:00
|
|
|
|
|
2003-10-16 18:31:38 +00:00
|
|
|
|
#ifdef SIGPIPE
|
|
|
|
|
/*
|
|
|
|
|
* If SIGPIPE is not handled or ignored, we will abort on any attempt
|
|
|
|
|
* to write to a pipe/socket that has been closed by the other end!
|
|
|
|
|
* We therefore need to ignore the signal if nothing else is already
|
|
|
|
|
* handling it.
|
|
|
|
|
*/
|
|
|
|
|
#ifdef HAVE_SIGACTION
|
|
|
|
|
{
|
|
|
|
|
struct sigaction act;
|
|
|
|
|
|
2003-12-01 06:55:40 +00:00
|
|
|
|
if (sigaction(SIGPIPE, 0, &act) == 0)
|
2003-10-16 18:31:38 +00:00
|
|
|
|
{
|
2003-12-01 06:55:40 +00:00
|
|
|
|
if (act.sa_handler == SIG_DFL)
|
2003-10-16 18:31:38 +00:00
|
|
|
|
{
|
2003-12-01 06:55:40 +00:00
|
|
|
|
// Not ignored or handled ... so we ignore it.
|
|
|
|
|
act.sa_handler = SIG_IGN;
|
|
|
|
|
if (sigaction(SIGPIPE, &act, 0) != 0)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Unable to ignore SIGPIPE\n");
|
|
|
|
|
}
|
2003-10-16 18:31:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "Unable to retrieve information about SIGPIPE\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-02-10 12:49:06 +00:00
|
|
|
|
#else /* HAVE_SIGACTION */
|
2003-10-16 18:31:38 +00:00
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
|
void (*handler)(NSInteger);
|
2003-10-16 18:31:38 +00:00
|
|
|
|
|
|
|
|
|
handler = signal(SIGPIPE, SIG_IGN);
|
|
|
|
|
if (handler != SIG_DFL)
|
|
|
|
|
{
|
|
|
|
|
signal(SIGPIPE, handler);
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-02-10 12:49:06 +00:00
|
|
|
|
#endif /* HAVE_SIGACTION */
|
|
|
|
|
#endif /* SIGPIPE */
|
2010-03-19 12:10:11 +00:00
|
|
|
|
#endif /* __MINGW__ */
|
2009-02-10 12:49:06 +00:00
|
|
|
|
|
|
|
|
|
finalize_sel = @selector(finalize);
|
2011-02-20 08:32:54 +00:00
|
|
|
|
finalize_imp = class_getMethodImplementation(self, finalize_sel);
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2011-06-18 12:57:30 +00:00
|
|
|
|
#if defined(__FreeBSD__) && defined(__i386__)
|
1999-11-04 20:08:14 +00:00
|
|
|
|
// Manipulate the FPU to add the exception mask. (Fixes SIGFPE
|
|
|
|
|
// problems on *BSD)
|
2007-01-23 16:04:29 +00:00
|
|
|
|
// Note this only works on x86
|
2010-05-30 16:06:04 +00:00
|
|
|
|
# if defined(FE_INVALID)
|
2009-08-15 21:44:21 +00:00
|
|
|
|
fedisableexcept(FE_INVALID);
|
2010-05-30 16:06:04 +00:00
|
|
|
|
# else
|
|
|
|
|
{
|
|
|
|
|
volatile short cw;
|
|
|
|
|
|
|
|
|
|
__asm__ volatile ("fstcw (%0)" : : "g" (&cw));
|
|
|
|
|
cw |= 1; /* Mask 'invalid' exception */
|
|
|
|
|
__asm__ volatile ("fldcw (%0)" : : "g" (&cw));
|
|
|
|
|
}
|
|
|
|
|
# endif
|
1999-11-04 20:08:14 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2011-02-12 16:33:40 +00:00
|
|
|
|
|
2002-12-05 04:24:43 +00:00
|
|
|
|
#ifdef HAVE_LOCALE_H
|
2011-02-12 16:33:40 +00:00
|
|
|
|
/* Set up locale from environment.
|
|
|
|
|
* This function should not use any ObjC code since important
|
|
|
|
|
* classes are not yet initialized.
|
|
|
|
|
*/
|
|
|
|
|
GSSetLocaleC(LC_ALL, "");
|
2002-12-05 04:24:43 +00:00
|
|
|
|
#endif
|
2001-05-03 15:32:31 +00:00
|
|
|
|
|
2011-02-12 16:33:40 +00:00
|
|
|
|
/* Create the global lock.
|
|
|
|
|
* NB. Ths is one of the first things we do ... setting up a new lock
|
|
|
|
|
* must not call any other Objective-C classes and must not involve
|
|
|
|
|
* any use of the autorelease system.
|
|
|
|
|
*/
|
2002-06-12 04:29:59 +00:00
|
|
|
|
gnustep_global_lock = [NSRecursiveLock new];
|
2002-03-27 09:55:57 +00:00
|
|
|
|
|
2011-02-12 16:33:40 +00:00
|
|
|
|
/* Behavior debugging ... enable with environment variable if needed.
|
|
|
|
|
*/
|
2010-03-08 09:27:48 +00:00
|
|
|
|
GSObjCBehaviorDebug(GSPrivateEnvironmentFlag("GNUSTEP_BEHAVIOR_DEBUG",
|
|
|
|
|
GSObjCBehaviorDebug(-1)));
|
|
|
|
|
|
2011-06-19 13:34:17 +00:00
|
|
|
|
/* See if we should cleanup at process exit.
|
|
|
|
|
*/
|
|
|
|
|
if (YES == GSPrivateEnvironmentFlag("GNUSTEP_SHOULD_CLEAN_UP", NO))
|
|
|
|
|
{
|
|
|
|
|
[self setShouldCleanUp: YES];
|
2011-06-20 07:33:27 +00:00
|
|
|
|
[self registerAtExit: @selector(_atExit)];
|
2011-06-19 13:34:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-02-12 16:33:40 +00:00
|
|
|
|
/* Set up the autorelease system ... we must do this before using any
|
|
|
|
|
* other class whose +initialize might autorelease something.
|
|
|
|
|
*/
|
1999-09-28 19:35:09 +00:00
|
|
|
|
autorelease_class = [NSAutoreleasePool class];
|
2000-10-30 18:00:27 +00:00
|
|
|
|
autorelease_sel = @selector(addObject:);
|
1999-09-28 19:35:09 +00:00
|
|
|
|
autorelease_imp = [autorelease_class methodForSelector: autorelease_sel];
|
2011-02-11 10:00:00 +00:00
|
|
|
|
|
2011-02-12 16:33:40 +00:00
|
|
|
|
/* Make sure the constant string class works and set up well-known
|
|
|
|
|
* string constants etc.
|
|
|
|
|
*/
|
2001-06-06 15:18:28 +00:00
|
|
|
|
NSConstantStringClass = [NSString constantStringClass];
|
2011-06-19 09:26:03 +00:00
|
|
|
|
|
2006-10-20 10:56:27 +00:00
|
|
|
|
GSPrivateBuildStrings();
|
2011-02-11 10:00:00 +00:00
|
|
|
|
|
2011-02-12 16:33:40 +00:00
|
|
|
|
/* Determine zombie management flags and set up a map to store
|
|
|
|
|
* information about zombie objects.
|
|
|
|
|
*/
|
|
|
|
|
NSZombieEnabled = GSPrivateEnvironmentFlag("NSZombieEnabled", NO);
|
|
|
|
|
NSDeallocateZombies = GSPrivateEnvironmentFlag("NSDeallocateZombies", NO);
|
|
|
|
|
zombieMap = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
|
|
|
|
|
NSNonOwnedPointerMapValueCallBacks, 0);
|
|
|
|
|
|
|
|
|
|
/* We need to cache the zombie class.
|
|
|
|
|
* We can't call +class because NSZombie doesn't have that method.
|
|
|
|
|
* We can't use NSClassFromString() because that would use an NSString
|
|
|
|
|
* object, and that class hasn't been initialized yet ...
|
|
|
|
|
*/
|
|
|
|
|
zombieClass = objc_lookUpClass("NSZombie");
|
|
|
|
|
|
|
|
|
|
/* Now that we have a workign autorelease system and working string
|
|
|
|
|
* classes we are able to set up notifications.
|
|
|
|
|
*/
|
1999-12-13 12:14:01 +00:00
|
|
|
|
[[NSNotificationCenter defaultCenter]
|
|
|
|
|
addObserver: self
|
|
|
|
|
selector: @selector(_becomeMultiThreaded:)
|
|
|
|
|
name: NSWillBecomeMultiThreadedNotification
|
|
|
|
|
object: nil];
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-20 07:33:27 +00:00
|
|
|
|
+ (void) _atExit
|
|
|
|
|
{
|
|
|
|
|
DESTROY(zombieMap);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* Allocates a new instance of the receiver from the default
|
|
|
|
|
* zone, by invoking +allocWithZone: with
|
|
|
|
|
* <code>NSDefaultMallocZone()</code> as the zone argument.<br />
|
|
|
|
|
* Returns the created instance.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
+ (id) alloc
|
|
|
|
|
{
|
1997-01-06 21:34:06 +00:00
|
|
|
|
return [self allocWithZone: NSDefaultMallocZone()];
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* This is the basic method to create a new instance. It
|
|
|
|
|
* allocates a new instance of the receiver from the specified
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* memory zone.
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* <p>
|
|
|
|
|
* Memory for an instance of the receiver is allocated; a
|
|
|
|
|
* pointer to this newly created instance is returned. All
|
2011-02-20 16:21:43 +00:00
|
|
|
|
* instance variables are set to 0. No initialization of the
|
|
|
|
|
* instance is performed apart from setup to be an instance of
|
|
|
|
|
* the correct class: it is your responsibility to initialize the
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* instance by calling an appropriate <code>init</code>
|
|
|
|
|
* method. If you are not using the garbage collector, it is
|
|
|
|
|
* also your responsibility to make sure the returned
|
|
|
|
|
* instance is destroyed when you finish using it, by calling
|
|
|
|
|
* the <code>release</code> method to destroy the instance
|
|
|
|
|
* directly, or by using <code>autorelease</code> and
|
|
|
|
|
* autorelease pools.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* You do not normally need to override this method in
|
|
|
|
|
* subclasses, unless you are implementing a class which for
|
|
|
|
|
* some reasons silently allocates instances of another class
|
|
|
|
|
* (this is typically needed to implement class clusters and
|
|
|
|
|
* similar design schemes).
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* If you have turned on debugging of object allocation (by
|
|
|
|
|
* calling the <code>GSDebugAllocationActive</code>
|
|
|
|
|
* function), this method will also update the various
|
|
|
|
|
* debugging counts and monitors of allocated objects, which
|
|
|
|
|
* you can access using the <code>GSDebugAllocation...</code>
|
|
|
|
|
* functions.
|
|
|
|
|
* </p>
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
+ (id) allocWithZone: (NSZone*)z
|
|
|
|
|
{
|
1996-01-26 19:18:08 +00:00
|
|
|
|
return NSAllocateObject (self, 0, z);
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the receiver.
|
|
|
|
|
*/
|
1998-07-15 12:48:14 +00:00
|
|
|
|
+ (id) copyWithZone: (NSZone*)z
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
1998-07-15 12:48:14 +00:00
|
|
|
|
return self;
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* <p>
|
|
|
|
|
* This method is a short-hand for alloc followed by init, that is,
|
|
|
|
|
* </p>
|
|
|
|
|
* <p><code>
|
|
|
|
|
* NSObject *object = [NSObject new];
|
|
|
|
|
* </code></p>
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* is exactly the same as
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* <p><code>
|
|
|
|
|
* NSObject *object = [[NSObject alloc] init];
|
|
|
|
|
* </code></p>
|
|
|
|
|
* <p>
|
|
|
|
|
* This is a general convention: all <code>new...</code>
|
|
|
|
|
* methods are supposed to return a newly allocated and
|
|
|
|
|
* initialized instance, as would be generated by an
|
|
|
|
|
* <code>alloc</code> method followed by a corresponding
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* <code>init...</code> method. Please note that if you are
|
|
|
|
|
* not using a garbage collector, this means that instances
|
|
|
|
|
* generated by the <code>new...</code> methods are not
|
|
|
|
|
* autoreleased, that is, you are responsible for releasing
|
|
|
|
|
* (autoreleasing) the instances yourself. So when you use
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* <code>new</code> you typically do something like:
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* <code>
|
|
|
|
|
* NSMutableArray *array = AUTORELEASE ([NSMutableArray new]);
|
|
|
|
|
* </code>
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
2002-08-20 15:07:58 +00:00
|
|
|
|
* You do not normally need to override <code>new</code> in
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* subclasses, because if you override <code>init</code> (and
|
|
|
|
|
* optionally <code>allocWithZone:</code> if you really
|
|
|
|
|
* need), <code>new</code> will automatically use your
|
|
|
|
|
* subclass methods.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* You might need instead to define new <code>new...</code>
|
|
|
|
|
* methods specific to your subclass to match any
|
|
|
|
|
* <code>init...</code> specific to your subclass. For
|
|
|
|
|
* example, if your subclass defines an instance method
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* <code>initWithName:</code>
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* </p>
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* <p>
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* it might be handy for you to have a class method
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* <code>newWithName:</code>
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* </p>
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* <p>
|
|
|
|
|
* which combines <code>alloc</code> and
|
|
|
|
|
* <code>initWithName:</code>. You would implement it as follows:
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* <code>
|
|
|
|
|
* + (id) newWithName: (NSString *)aName
|
|
|
|
|
* {
|
|
|
|
|
* return [[self alloc] initWithName: aName];
|
|
|
|
|
* }
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* </code>
|
|
|
|
|
* </p>
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1998-07-15 12:48:14 +00:00
|
|
|
|
+ (id) new
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
1998-07-15 12:48:14 +00:00
|
|
|
|
return [[self alloc] init];
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-09 04:57:04 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the class of which the receiver is an instance.<br />
|
2011-02-20 16:21:43 +00:00
|
|
|
|
* The default implementation returns the actual class that the
|
|
|
|
|
* receiver is an instance of.<br />
|
|
|
|
|
* NB. When NSZombie is enabled (see NSDebug.h) this is changed
|
|
|
|
|
* to be the NSZombie class upon object deallocation.
|
2002-06-09 04:57:04 +00:00
|
|
|
|
*/
|
|
|
|
|
- (Class) class
|
|
|
|
|
{
|
2011-02-10 18:40:18 +00:00
|
|
|
|
return object_getClass(self);
|
2002-06-09 04:57:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the name of the class of the receiving object by using
|
|
|
|
|
* the NSStringFromClass() function.<br />
|
|
|
|
|
* This is a MacOS-X addition for apple scripting, which is also
|
|
|
|
|
* generally useful.
|
|
|
|
|
*/
|
|
|
|
|
- (NSString*) className
|
|
|
|
|
{
|
|
|
|
|
return NSStringFromClass([self class]);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* Creates and returns a copy of the receiver by calling -copyWithZone:
|
2002-06-01 08:55:19 +00:00
|
|
|
|
* passing NSDefaultMallocZone()
|
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
- (id) copy
|
|
|
|
|
{
|
2002-06-01 08:55:19 +00:00
|
|
|
|
return [(id)self copyWithZone: NSDefaultMallocZone()];
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2002-08-07 15:30:03 +00:00
|
|
|
|
* Deallocates the receiver by calling NSDeallocateObject() with self
|
|
|
|
|
* as the argument.<br />
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* <p>
|
|
|
|
|
* You should normally call the superclass implementation of this method
|
|
|
|
|
* when you override it in a subclass, or the memory occupied by your
|
|
|
|
|
* object will not be released.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* <code>NSObject</code>'s implementation of this method
|
|
|
|
|
* destroys the receiver, by returning the memory allocated
|
|
|
|
|
* to the receiver to the system. After this method has been
|
|
|
|
|
* called on an instance, you must not refer the instance in
|
|
|
|
|
* any way, because it does not exist any longer. If you do,
|
|
|
|
|
* it is a bug and your program might even crash with a
|
|
|
|
|
* segmentation fault.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* If you have turned on the debugging facilities for
|
|
|
|
|
* instance allocation, <code>NSObject</code>'s
|
|
|
|
|
* implementation of this method will also update the various
|
|
|
|
|
* counts and monitors of allocated instances (see the
|
|
|
|
|
* <code>GSDebugAllocation...</code> functions for more
|
|
|
|
|
* info).
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* Normally you are supposed to manage the memory taken by
|
|
|
|
|
* objects by using the high level interface provided by the
|
|
|
|
|
* <code>retain</code>, <code>release</code> and
|
|
|
|
|
* <code>autorelease</code> methods (or better by the
|
|
|
|
|
* corresponding macros <code>RETAIN</code>,
|
|
|
|
|
* <code>RELEASE</code> and <code>AUTORELEASE</code>), and by
|
|
|
|
|
* autorelease pools and such; whenever the
|
|
|
|
|
* release/autorelease mechanism determines that an object is
|
|
|
|
|
* no longer needed (which happens when its retain count
|
|
|
|
|
* reaches 0), it will call the <code>dealloc</code> method
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* to actually deallocate the object. This means that normally,
|
|
|
|
|
* you should not need to call <code>dealloc</code> directly as
|
|
|
|
|
* the gnustep base library automatically calls it for you when
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* the retain count of an object reaches 0.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* Because the <code>dealloc</code> method will be called
|
|
|
|
|
* when an instance is being destroyed, if instances of your
|
|
|
|
|
* subclass use objects or resources (as it happens for most
|
|
|
|
|
* useful classes), you must override <code>dealloc</code> in
|
|
|
|
|
* subclasses to release all objects and resources which are
|
|
|
|
|
* used by the instance, otherwise these objects and
|
|
|
|
|
* resources would be leaked. In the subclass
|
|
|
|
|
* implementation, you should first release all your subclass
|
|
|
|
|
* specific objects and resources, and then invoke super's
|
|
|
|
|
* implementation (which will do the same, and so on up in
|
|
|
|
|
* the class hierarchy to <code>NSObject</code>'s
|
|
|
|
|
* implementation, which finally destroys the object). Here
|
|
|
|
|
* is an example of the implementation of
|
|
|
|
|
* <code>dealloc</code> for a subclass whose instances have a
|
|
|
|
|
* single instance variable <code>name</code> which needs to
|
|
|
|
|
* be released when an instance is deallocated:
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* <code>
|
|
|
|
|
* - (void) dealloc
|
|
|
|
|
* {
|
|
|
|
|
* RELEASE (name);
|
|
|
|
|
* [super dealloc];
|
|
|
|
|
* }
|
|
|
|
|
* </code>
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* <code>dealloc</code> might contain code to release not
|
|
|
|
|
* only objects, but also other resources, such as open
|
|
|
|
|
* files, network connections, raw memory allocated in other
|
|
|
|
|
* ways, etc.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
|
|
|
|
* If you have allocated the memory using a non-standard mechanism, you
|
|
|
|
|
* will not call the superclass (NSObject) implementation of the method
|
|
|
|
|
* as you will need to handle the deallocation specially.<br />
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* In some circumstances, an object may wish to prevent itself from
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* being deallocated, it can do this simply be refraining from calling
|
|
|
|
|
* the superclass implementation.
|
|
|
|
|
* </p>
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
- (void) dealloc
|
|
|
|
|
{
|
1996-01-26 19:18:08 +00:00
|
|
|
|
NSDeallocateObject (self);
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-01-12 18:36:37 +00:00
|
|
|
|
- (void) finalize
|
|
|
|
|
{
|
2011-04-05 12:13:12 +00:00
|
|
|
|
Class destructorClass = object_getClass(self);
|
|
|
|
|
IMP destructor = 0;
|
|
|
|
|
|
|
|
|
|
/* C++ destructors must be called in the opposite order to their
|
|
|
|
|
* creators, so start at the leaf class and then go up the tree until we
|
|
|
|
|
* get to the root class. As a small optimisation, we don't bother
|
|
|
|
|
* visiting any classes that don't have an implementation of this method
|
|
|
|
|
* (including one inherited from a superclass).
|
|
|
|
|
*
|
|
|
|
|
* Care must be taken not to call inherited .cxx_destruct methods.
|
|
|
|
|
*/
|
|
|
|
|
while (class_respondsToSelector(destructorClass, cxx_destruct))
|
|
|
|
|
{
|
|
|
|
|
IMP newDestructor;
|
|
|
|
|
|
|
|
|
|
newDestructor
|
|
|
|
|
= class_getMethodImplementation(destructorClass, cxx_destruct);
|
|
|
|
|
if (newDestructor != destructor)
|
|
|
|
|
{
|
|
|
|
|
newDestructor(self, cxx_destruct);
|
|
|
|
|
destructor = newDestructor;
|
|
|
|
|
}
|
|
|
|
|
destructorClass = class_getSuperclass(destructorClass);
|
|
|
|
|
}
|
2009-01-12 18:36:37 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-22 22:40:40 +00:00
|
|
|
|
/**
|
|
|
|
|
* This method is an anachronism. Do not use it.
|
|
|
|
|
*/
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (id) free
|
1995-01-26 17:55:52 +00:00
|
|
|
|
{
|
1996-03-26 19:35:47 +00:00
|
|
|
|
[NSException raise: NSGenericException
|
2000-06-30 11:59:59 +00:00
|
|
|
|
format: @"Use `dealloc' instead of `free' for %@.", self];
|
1995-01-26 17:55:52 +00:00
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Initialises the receiver ... the NSObject implementation simply returns self.
|
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
- (id) init
|
|
|
|
|
{
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* Creates and returns a mutable copy of the receiver by calling
|
2002-06-01 08:55:19 +00:00
|
|
|
|
* -mutableCopyWithZone: passing NSDefaultMallocZone().
|
|
|
|
|
*/
|
1995-03-12 15:40:22 +00:00
|
|
|
|
- (id) mutableCopy
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
2002-06-01 08:55:19 +00:00
|
|
|
|
return [(id)self mutableCopyWithZone: NSDefaultMallocZone()];
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* Returns the super class from which the receiver was derived.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1995-04-01 20:21:53 +00:00
|
|
|
|
+ (Class) superclass
|
|
|
|
|
{
|
2010-02-22 10:13:20 +00:00
|
|
|
|
return class_getSuperclass(self);
|
1995-04-01 20:21:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* Returns the super class from which the receivers class was derived.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1995-03-12 15:40:22 +00:00
|
|
|
|
- (Class) superclass
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
2010-02-22 10:13:20 +00:00
|
|
|
|
return class_getSuperclass(object_getClass(self));
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a flag to say if instances of the receiver class will
|
|
|
|
|
* respond to the specified selector. This ignores situations
|
|
|
|
|
* where a subclass implements -forwardInvocation: to respond to
|
|
|
|
|
* selectors not normally handled ... in these cases the subclass
|
|
|
|
|
* may override this method to handle it.
|
2003-02-18 11:43:57 +00:00
|
|
|
|
* <br />If given a null selector, raises NSInvalidArgumentException when
|
|
|
|
|
* in MacOS-X compatibility more, or returns NO otherwise.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
+ (BOOL) instancesRespondToSelector: (SEL)aSelector
|
|
|
|
|
{
|
2002-08-27 17:02:05 +00:00
|
|
|
|
if (aSelector == 0)
|
2003-02-18 11:43:57 +00:00
|
|
|
|
{
|
2006-10-20 10:56:27 +00:00
|
|
|
|
if (GSPrivateDefaultsFlag(GSMacOSXCompatible))
|
2003-02-18 11:43:57 +00:00
|
|
|
|
{
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%@ null selector given",
|
|
|
|
|
NSStringFromSelector(_cmd)];
|
|
|
|
|
}
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
2011-04-03 04:25:52 +00:00
|
|
|
|
return class_respondsToSelector(self, aSelector) ? YES : NO;
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a flag to say whether the receiving class conforms to aProtocol
|
|
|
|
|
*/
|
1995-03-27 17:25:42 +00:00
|
|
|
|
+ (BOOL) conformsToProtocol: (Protocol*)aProtocol
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
2010-12-24 17:19:40 +00:00
|
|
|
|
#ifdef __GNU_LIBOBJC__
|
2010-12-24 15:37:06 +00:00
|
|
|
|
Class c;
|
|
|
|
|
|
|
|
|
|
/* Iterate over the current class and all the superclasses. */
|
|
|
|
|
for (c = self; c != Nil; c = class_getSuperclass (c))
|
|
|
|
|
{
|
|
|
|
|
if (class_conformsToProtocol(c, aProtocol))
|
|
|
|
|
{
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NO;
|
2010-12-24 17:19:40 +00:00
|
|
|
|
#else
|
|
|
|
|
/* libobjc2 and ObjectiveC2/ have an implementation of
|
|
|
|
|
class_conformsToProtocol() which automatically looks up the
|
|
|
|
|
protocol in superclasses (unlike the Apple and GNU Objective-C
|
|
|
|
|
runtime ones). */
|
|
|
|
|
return class_conformsToProtocol(self, aProtocol);
|
|
|
|
|
#endif
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a flag to say whether the class of the receiver conforms
|
|
|
|
|
* to aProtocol.
|
|
|
|
|
*/
|
1995-03-27 17:25:42 +00:00
|
|
|
|
- (BOOL) conformsToProtocol: (Protocol*)aProtocol
|
|
|
|
|
{
|
2010-12-24 15:37:06 +00:00
|
|
|
|
return [[self class] conformsToProtocol: aProtocol];
|
1995-03-27 17:25:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 17:02:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a pointer to the C function implementing the method used
|
|
|
|
|
* to respond to messages with aSelector by instances of the receiving
|
|
|
|
|
* class.
|
|
|
|
|
* <br />Raises NSInvalidArgumentException if given a null selector.
|
|
|
|
|
*/
|
1998-11-02 10:17:28 +00:00
|
|
|
|
+ (IMP) instanceMethodForSelector: (SEL)aSelector
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
2002-08-27 17:02:05 +00:00
|
|
|
|
if (aSelector == 0)
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
|
1998-10-26 12:14:12 +00:00
|
|
|
|
/*
|
2011-02-20 08:32:54 +00:00
|
|
|
|
* Since 'self' is an class, class_getMethodImplementation() will get
|
|
|
|
|
* the instance method.
|
1998-10-26 12:14:12 +00:00
|
|
|
|
*/
|
2011-02-20 08:32:54 +00:00
|
|
|
|
return class_getMethodImplementation((Class)self, aSelector);
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
1998-10-26 12:14:12 +00:00
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a pointer to the C function implementing the method used
|
|
|
|
|
* to respond to messages with aSelector.
|
2002-08-27 17:02:05 +00:00
|
|
|
|
* <br />Raises NSInvalidArgumentException if given a null selector.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
- (IMP) methodForSelector: (SEL)aSelector
|
|
|
|
|
{
|
2002-08-27 17:02:05 +00:00
|
|
|
|
if (aSelector == 0)
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
|
1998-10-26 12:14:12 +00:00
|
|
|
|
/*
|
2010-02-22 10:13:20 +00:00
|
|
|
|
* If 'self' is an instance, object_getClass() will get the class,
|
2011-02-20 08:32:54 +00:00
|
|
|
|
* and class_getMethodImplementation() will get the instance method.
|
2010-02-22 10:13:20 +00:00
|
|
|
|
* If 'self' is a class, object_getClass() will get the meta-class,
|
2011-02-20 08:32:54 +00:00
|
|
|
|
* and class_getMethodImplementation() will get the class method.
|
1998-10-26 12:14:12 +00:00
|
|
|
|
*/
|
2011-02-20 08:32:54 +00:00
|
|
|
|
return class_getMethodImplementation(object_getClass(self), aSelector);
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a pointer to the C function implementing the method used
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* to respond to messages with aSelector which are sent to instances
|
2002-06-01 08:55:19 +00:00
|
|
|
|
* of the receiving class.
|
2002-08-27 17:02:05 +00:00
|
|
|
|
* <br />Raises NSInvalidArgumentException if given a null selector.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1998-07-29 09:36:16 +00:00
|
|
|
|
+ (NSMethodSignature*) instanceMethodSignatureForSelector: (SEL)aSelector
|
|
|
|
|
{
|
2002-08-27 17:02:05 +00:00
|
|
|
|
struct objc_method *mth;
|
|
|
|
|
|
|
|
|
|
if (aSelector == 0)
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
|
|
|
|
|
|
2004-08-20 17:53:16 +00:00
|
|
|
|
mth = GSGetMethod(self, aSelector, YES, YES);
|
2011-03-09 12:01:04 +00:00
|
|
|
|
if (0 == mth)
|
2006-05-15 12:07:35 +00:00
|
|
|
|
return nil;
|
2011-03-09 12:01:04 +00:00
|
|
|
|
return [NSMethodSignature
|
|
|
|
|
signatureWithObjCTypes: method_getTypeEncoding(mth)];
|
1998-07-29 09:36:16 +00:00
|
|
|
|
}
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the method signature describing how the receiver would handle
|
|
|
|
|
* a message with aSelector.
|
2010-08-17 18:36:46 +00:00
|
|
|
|
* <br />Returns nil if given a null selector.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
|
|
|
|
|
{
|
2011-03-09 12:01:04 +00:00
|
|
|
|
const char *types = NULL;
|
|
|
|
|
Class c;
|
|
|
|
|
unsigned int count;
|
|
|
|
|
Protocol **protocols;
|
2001-01-03 11:22:59 +00:00
|
|
|
|
|
2010-08-17 18:36:46 +00:00
|
|
|
|
if (0 == aSelector)
|
|
|
|
|
{
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
2002-08-27 17:02:05 +00:00
|
|
|
|
|
2011-03-09 12:01:04 +00:00
|
|
|
|
c = object_getClass(self);
|
2003-07-04 09:33:53 +00:00
|
|
|
|
|
2011-03-09 12:01:04 +00:00
|
|
|
|
/* Do a fast lookup to see if the method is implemented at all. If it isn't,
|
|
|
|
|
* we can give up without doing a very expensive linear search through every
|
|
|
|
|
* method list in the class hierarchy.
|
|
|
|
|
*/
|
|
|
|
|
if (!class_respondsToSelector(c, aSelector))
|
2001-04-10 03:27:01 +00:00
|
|
|
|
{
|
2003-07-04 09:33:53 +00:00
|
|
|
|
return nil; // Method not implemented
|
2001-04-10 03:27:01 +00:00
|
|
|
|
}
|
2011-03-09 12:01:04 +00:00
|
|
|
|
|
|
|
|
|
/* If there are protocols that this class conforms to,
|
2003-07-04 09:33:53 +00:00
|
|
|
|
* the method may be listed in a protocol with more
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* detailed type information than in the class itself
|
2003-07-04 09:33:53 +00:00
|
|
|
|
* and we must therefore use the information from the
|
|
|
|
|
* protocol.
|
|
|
|
|
* This is because protocols also carry information
|
|
|
|
|
* used by the Distributed Objects system, which the
|
|
|
|
|
* runtime does not maintain in classes.
|
|
|
|
|
*/
|
2011-03-09 12:01:04 +00:00
|
|
|
|
protocols = class_copyProtocolList(c, &count);
|
A huge blob of changes to make -base build with libobjc2, without using the old libobjc2 headers.
Most of these changes involve simply removing direct manipulation of any runtime structures and replacing them with runtime function calls. For example class->name becomes class_getName(class) and so on.
libobjc2, like the Apple runtime, the NeXT runtime, and every version of the Objective-C spec, calls the class pointer in id isa. A few files now have #define class_pointer isa at the top. This line replaces class_pointer in the old GNU libobjc headers with isa so either class_pointer or isa can be used for accessing the class of an object. Note: object_getClass() should be used in most cases because, in some future version of the runtime, this will skip things like lock classes and other hidden classes (e.g. KVO classes).
All of the old forwarding stuff has been removed. Most of this stuff followed convoluted code paths that ended with an exception. A few simply broke in exciting ways. Hopefully no one has used them for the last ten years or so, but we can bring them back with some #ifndef stuff if they're really needed by anyone.
There is currently a bug in configure, which prevents dladdr() from being detected, so you need to manually tweak config.h to build - I have not fixed the fall-back code in objc-load.m to work with libobjc2, I just added a new version that uses the loader's functionality directly.
Although -base now builds, it builds with a lot of warnings. <string.h> is missing from a lot of files, so memcpy() and strlen() generate implicit function declaration warnings.
Additionally, libobjc2 does still provide the sel_{get,register}_*() functions, but they're wrappers around the newer API ones. These are deprecated and are not exposed in the headers. Although they work, we should be replacing them with the libobjc2 versions as soon as possible.
This incorporates a patch by Eric.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31265 72102866-910b-0410-8b05-ffd578937521
2010-09-09 15:06:09 +00:00
|
|
|
|
if (NULL != protocols)
|
2003-07-04 09:33:53 +00:00
|
|
|
|
{
|
A huge blob of changes to make -base build with libobjc2, without using the old libobjc2 headers.
Most of these changes involve simply removing direct manipulation of any runtime structures and replacing them with runtime function calls. For example class->name becomes class_getName(class) and so on.
libobjc2, like the Apple runtime, the NeXT runtime, and every version of the Objective-C spec, calls the class pointer in id isa. A few files now have #define class_pointer isa at the top. This line replaces class_pointer in the old GNU libobjc headers with isa so either class_pointer or isa can be used for accessing the class of an object. Note: object_getClass() should be used in most cases because, in some future version of the runtime, this will skip things like lock classes and other hidden classes (e.g. KVO classes).
All of the old forwarding stuff has been removed. Most of this stuff followed convoluted code paths that ended with an exception. A few simply broke in exciting ways. Hopefully no one has used them for the last ten years or so, but we can bring them back with some #ifndef stuff if they're really needed by anyone.
There is currently a bug in configure, which prevents dladdr() from being detected, so you need to manually tweak config.h to build - I have not fixed the fall-back code in objc-load.m to work with libobjc2, I just added a new version that uses the loader's functionality directly.
Although -base now builds, it builds with a lot of warnings. <string.h> is missing from a lot of files, so memcpy() and strlen() generate implicit function declaration warnings.
Additionally, libobjc2 does still provide the sel_{get,register}_*() functions, but they're wrappers around the newer API ones. These are deprecated and are not exposed in the headers. Although they work, we should be replacing them with the libobjc2 versions as soon as possible.
This incorporates a patch by Eric.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31265 72102866-910b-0410-8b05-ffd578937521
2010-09-09 15:06:09 +00:00
|
|
|
|
struct objc_method_description mth;
|
2010-09-09 17:02:19 +00:00
|
|
|
|
int i;
|
2011-03-09 12:01:04 +00:00
|
|
|
|
|
|
|
|
|
for (i = 0 ; i < count ; i++)
|
A huge blob of changes to make -base build with libobjc2, without using the old libobjc2 headers.
Most of these changes involve simply removing direct manipulation of any runtime structures and replacing them with runtime function calls. For example class->name becomes class_getName(class) and so on.
libobjc2, like the Apple runtime, the NeXT runtime, and every version of the Objective-C spec, calls the class pointer in id isa. A few files now have #define class_pointer isa at the top. This line replaces class_pointer in the old GNU libobjc headers with isa so either class_pointer or isa can be used for accessing the class of an object. Note: object_getClass() should be used in most cases because, in some future version of the runtime, this will skip things like lock classes and other hidden classes (e.g. KVO classes).
All of the old forwarding stuff has been removed. Most of this stuff followed convoluted code paths that ended with an exception. A few simply broke in exciting ways. Hopefully no one has used them for the last ten years or so, but we can bring them back with some #ifndef stuff if they're really needed by anyone.
There is currently a bug in configure, which prevents dladdr() from being detected, so you need to manually tweak config.h to build - I have not fixed the fall-back code in objc-load.m to work with libobjc2, I just added a new version that uses the loader's functionality directly.
Although -base now builds, it builds with a lot of warnings. <string.h> is missing from a lot of files, so memcpy() and strlen() generate implicit function declaration warnings.
Additionally, libobjc2 does still provide the sel_{get,register}_*() functions, but they're wrappers around the newer API ones. These are deprecated and are not exposed in the headers. Although they work, we should be replacing them with the libobjc2 versions as soon as possible.
This incorporates a patch by Eric.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31265 72102866-910b-0410-8b05-ffd578937521
2010-09-09 15:06:09 +00:00
|
|
|
|
{
|
|
|
|
|
mth = GSProtocolGetMethodDescriptionRecursive(protocols[i],
|
2011-03-09 12:01:04 +00:00
|
|
|
|
aSelector, YES, YES);
|
A huge blob of changes to make -base build with libobjc2, without using the old libobjc2 headers.
Most of these changes involve simply removing direct manipulation of any runtime structures and replacing them with runtime function calls. For example class->name becomes class_getName(class) and so on.
libobjc2, like the Apple runtime, the NeXT runtime, and every version of the Objective-C spec, calls the class pointer in id isa. A few files now have #define class_pointer isa at the top. This line replaces class_pointer in the old GNU libobjc headers with isa so either class_pointer or isa can be used for accessing the class of an object. Note: object_getClass() should be used in most cases because, in some future version of the runtime, this will skip things like lock classes and other hidden classes (e.g. KVO classes).
All of the old forwarding stuff has been removed. Most of this stuff followed convoluted code paths that ended with an exception. A few simply broke in exciting ways. Hopefully no one has used them for the last ten years or so, but we can bring them back with some #ifndef stuff if they're really needed by anyone.
There is currently a bug in configure, which prevents dladdr() from being detected, so you need to manually tweak config.h to build - I have not fixed the fall-back code in objc-load.m to work with libobjc2, I just added a new version that uses the loader's functionality directly.
Although -base now builds, it builds with a lot of warnings. <string.h> is missing from a lot of files, so memcpy() and strlen() generate implicit function declaration warnings.
Additionally, libobjc2 does still provide the sel_{get,register}_*() functions, but they're wrappers around the newer API ones. These are deprecated and are not exposed in the headers. Although they work, we should be replacing them with the libobjc2 versions as soon as possible.
This incorporates a patch by Eric.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31265 72102866-910b-0410-8b05-ffd578937521
2010-09-09 15:06:09 +00:00
|
|
|
|
if (NULL == mth.types)
|
|
|
|
|
{
|
|
|
|
|
// Search for class method
|
|
|
|
|
mth = GSProtocolGetMethodDescriptionRecursive(protocols[i],
|
2011-03-09 12:01:04 +00:00
|
|
|
|
aSelector, YES, NO);
|
A huge blob of changes to make -base build with libobjc2, without using the old libobjc2 headers.
Most of these changes involve simply removing direct manipulation of any runtime structures and replacing them with runtime function calls. For example class->name becomes class_getName(class) and so on.
libobjc2, like the Apple runtime, the NeXT runtime, and every version of the Objective-C spec, calls the class pointer in id isa. A few files now have #define class_pointer isa at the top. This line replaces class_pointer in the old GNU libobjc headers with isa so either class_pointer or isa can be used for accessing the class of an object. Note: object_getClass() should be used in most cases because, in some future version of the runtime, this will skip things like lock classes and other hidden classes (e.g. KVO classes).
All of the old forwarding stuff has been removed. Most of this stuff followed convoluted code paths that ended with an exception. A few simply broke in exciting ways. Hopefully no one has used them for the last ten years or so, but we can bring them back with some #ifndef stuff if they're really needed by anyone.
There is currently a bug in configure, which prevents dladdr() from being detected, so you need to manually tweak config.h to build - I have not fixed the fall-back code in objc-load.m to work with libobjc2, I just added a new version that uses the loader's functionality directly.
Although -base now builds, it builds with a lot of warnings. <string.h> is missing from a lot of files, so memcpy() and strlen() generate implicit function declaration warnings.
Additionally, libobjc2 does still provide the sel_{get,register}_*() functions, but they're wrappers around the newer API ones. These are deprecated and are not exposed in the headers. Although they work, we should be replacing them with the libobjc2 versions as soon as possible.
This incorporates a patch by Eric.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31265 72102866-910b-0410-8b05-ffd578937521
2010-09-09 15:06:09 +00:00
|
|
|
|
// FIXME: We should probably search optional methods here too.
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-09 12:01:04 +00:00
|
|
|
|
if (NULL != mth.types)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
A huge blob of changes to make -base build with libobjc2, without using the old libobjc2 headers.
Most of these changes involve simply removing direct manipulation of any runtime structures and replacing them with runtime function calls. For example class->name becomes class_getName(class) and so on.
libobjc2, like the Apple runtime, the NeXT runtime, and every version of the Objective-C spec, calls the class pointer in id isa. A few files now have #define class_pointer isa at the top. This line replaces class_pointer in the old GNU libobjc headers with isa so either class_pointer or isa can be used for accessing the class of an object. Note: object_getClass() should be used in most cases because, in some future version of the runtime, this will skip things like lock classes and other hidden classes (e.g. KVO classes).
All of the old forwarding stuff has been removed. Most of this stuff followed convoluted code paths that ended with an exception. A few simply broke in exciting ways. Hopefully no one has used them for the last ten years or so, but we can bring them back with some #ifndef stuff if they're really needed by anyone.
There is currently a bug in configure, which prevents dladdr() from being detected, so you need to manually tweak config.h to build - I have not fixed the fall-back code in objc-load.m to work with libobjc2, I just added a new version that uses the loader's functionality directly.
Although -base now builds, it builds with a lot of warnings. <string.h> is missing from a lot of files, so memcpy() and strlen() generate implicit function declaration warnings.
Additionally, libobjc2 does still provide the sel_{get,register}_*() functions, but they're wrappers around the newer API ones. These are deprecated and are not exposed in the headers. Although they work, we should be replacing them with the libobjc2 versions as soon as possible.
This incorporates a patch by Eric.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31265 72102866-910b-0410-8b05-ffd578937521
2010-09-09 15:06:09 +00:00
|
|
|
|
}
|
|
|
|
|
free(protocols);
|
2003-07-04 09:33:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-09-02 15:17:46 +00:00
|
|
|
|
if (types == 0)
|
|
|
|
|
{
|
|
|
|
|
#ifdef __GNUSTEP_RUNTIME__
|
2011-03-09 12:01:04 +00:00
|
|
|
|
struct objc_slot *objc_get_slot(Class cls, SEL selector);
|
|
|
|
|
struct objc_slot *slot = objc_get_slot(object_getClass(self), aSelector);
|
2010-09-02 15:17:46 +00:00
|
|
|
|
types = slot->types;
|
|
|
|
|
#else
|
2011-03-22 20:59:06 +00:00
|
|
|
|
struct objc_method *mth;
|
|
|
|
|
if (GSObjCIsInstance(self))
|
|
|
|
|
{
|
|
|
|
|
mth = GSGetMethod(object_getClass(self), aSelector, YES, YES);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mth = GSGetMethod((Class)self, aSelector, NO, YES);
|
|
|
|
|
}
|
2010-12-23 02:23:05 +00:00
|
|
|
|
types = method_getTypeEncoding (mth);
|
2010-09-02 15:17:46 +00:00
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-10 03:27:01 +00:00
|
|
|
|
if (types == 0)
|
2000-07-04 10:17:03 +00:00
|
|
|
|
{
|
2001-03-07 21:21:10 +00:00
|
|
|
|
return nil;
|
2000-07-04 10:17:03 +00:00
|
|
|
|
}
|
|
|
|
|
return [NSMethodSignature signatureWithObjCTypes: types];
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a string describing the receiver. The default implementation
|
2002-08-20 10:22:05 +00:00
|
|
|
|
* gives the class and memory location of the receiver.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1995-03-12 15:40:22 +00:00
|
|
|
|
- (NSString*) description
|
1995-01-26 17:55:52 +00:00
|
|
|
|
{
|
2006-11-06 13:05:52 +00:00
|
|
|
|
return [NSString stringWithFormat: @"<%s: %p>",
|
2010-02-22 10:13:20 +00:00
|
|
|
|
class_getName([self class]), self];
|
1995-01-26 17:55:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a string describing the receiving class. The default implementation
|
|
|
|
|
* gives the name of the class by calling NSStringFromClass().
|
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
+ (NSString*) description
|
|
|
|
|
{
|
2002-06-01 08:55:19 +00:00
|
|
|
|
return NSStringFromClass(self);
|
1998-12-18 17:05:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sets up the ObjC runtime so that the receiver is used wherever code
|
|
|
|
|
* calls for aClassObject to be used.
|
|
|
|
|
*/
|
1995-03-12 15:40:22 +00:00
|
|
|
|
+ (void) poseAsClass: (Class)aClassObject
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
2010-09-09 16:30:10 +00:00
|
|
|
|
[NSException raise: NSInternalInconsistencyException
|
|
|
|
|
format: @"Class posing is not supported"];
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* Raises an invalid argument exception providing information about
|
2002-06-01 08:55:19 +00:00
|
|
|
|
* the receivers inability to handle aSelector.
|
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
- (void) doesNotRecognizeSelector: (SEL)aSelector
|
|
|
|
|
{
|
1996-09-17 14:33:30 +00:00
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
2002-06-01 08:55:19 +00:00
|
|
|
|
format: @"%s(%s) does not recognize %s",
|
2005-02-22 11:22:44 +00:00
|
|
|
|
GSClassNameFromObject(self),
|
2002-01-31 15:41:47 +00:00
|
|
|
|
GSObjCIsInstance(self) ? "instance" : "class",
|
2010-02-22 10:13:20 +00:00
|
|
|
|
aSelector ? sel_getName(aSelector) : "(null)"];
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* This method is called automatically to handle a message sent to
|
|
|
|
|
* the receiver for which the receivers class has no method.<br />
|
2005-07-08 11:48:37 +00:00
|
|
|
|
* The default implementation calls -doesNotRecognizeSelector:
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
- (void) forwardInvocation: (NSInvocation*)anInvocation
|
|
|
|
|
{
|
2009-11-23 16:43:08 +00:00
|
|
|
|
id target = [self forwardingTargetForSelector: [anInvocation selector]];
|
2009-11-23 18:07:25 +00:00
|
|
|
|
|
2009-11-23 16:43:08 +00:00
|
|
|
|
if (nil != target)
|
2009-11-23 18:07:25 +00:00
|
|
|
|
{
|
|
|
|
|
[anInvocation invokeWithTarget: target];
|
|
|
|
|
return;
|
|
|
|
|
}
|
2002-06-01 08:55:19 +00:00
|
|
|
|
[self doesNotRecognizeSelector: [anInvocation selector]];
|
1994-11-08 16:44:01 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Called after the receiver has been created by decoding some sort
|
|
|
|
|
* of archive. Returns self. Subclasses may override this to perform
|
|
|
|
|
* some special initialisation upon being decoded.
|
|
|
|
|
*/
|
1995-01-26 17:55:52 +00:00
|
|
|
|
- (id) awakeAfterUsingCoder: (NSCoder*)aDecoder
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-22 22:40:40 +00:00
|
|
|
|
// FIXME - should this be added (as in OS X) now that we have NSKeyedArchiver?
|
|
|
|
|
// - (Class) classForKeyedArchiver
|
|
|
|
|
// {
|
|
|
|
|
// return [self classForArchiver];
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Override to substitute class when an instance is being archived by an
|
|
|
|
|
* [NSArchiver]. Default implementation returns -classForCoder.
|
|
|
|
|
*/
|
1998-10-11 06:26:40 +00:00
|
|
|
|
- (Class) classForArchiver
|
|
|
|
|
{
|
|
|
|
|
return [self classForCoder];
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-22 22:40:40 +00:00
|
|
|
|
/**
|
|
|
|
|
* Override to substitute class when an instance is being serialized by an
|
|
|
|
|
* [NSCoder]. Default implementation returns <code>[self class]</code> (no
|
|
|
|
|
* substitution).
|
|
|
|
|
*/
|
1994-11-08 16:44:01 +00:00
|
|
|
|
- (Class) classForCoder
|
|
|
|
|
{
|
|
|
|
|
return [self class];
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-22 22:40:40 +00:00
|
|
|
|
// FIXME - should this be added (as in OS X) now that we have NSKeyedArchiver?
|
2005-11-28 15:41:35 +00:00
|
|
|
|
// - (id) replacementObjectForKeyedArchiver: (NSKeyedArchiver *)keyedArchiver
|
2004-06-22 22:40:40 +00:00
|
|
|
|
// {
|
|
|
|
|
// return [self replacementObjectForCoder: (NSArchiver *)keyedArchiver];
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Override to substitute another object for this instance when being archived
|
|
|
|
|
* by given [NSArchiver]. Default implementation returns
|
|
|
|
|
* -replacementObjectForCoder:.
|
|
|
|
|
*/
|
1998-10-22 10:02:39 +00:00
|
|
|
|
- (id) replacementObjectForArchiver: (NSArchiver*)anArchiver
|
1998-10-11 06:26:40 +00:00
|
|
|
|
{
|
|
|
|
|
return [self replacementObjectForCoder: (NSCoder*)anArchiver];
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-22 22:40:40 +00:00
|
|
|
|
/**
|
|
|
|
|
* Override to substitute another object for this instance when being
|
|
|
|
|
* serialized by given [NSCoder]. Default implementation returns
|
|
|
|
|
* <code>self</code>.
|
|
|
|
|
*/
|
1995-03-12 15:40:22 +00:00
|
|
|
|
- (id) replacementObjectForCoder: (NSCoder*)anEncoder
|
|
|
|
|
{
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
1996-01-26 19:18:08 +00:00
|
|
|
|
|
1995-03-12 15:40:22 +00:00
|
|
|
|
/* NSObject protocol */
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Adds the receiver to the current autorelease pool, so that it will be
|
|
|
|
|
* sent a -release message when the pool is destroyed.<br />
|
2002-06-02 09:05:11 +00:00
|
|
|
|
* Returns the receiver.<br />
|
|
|
|
|
* In GNUstep, the [NSObject+enableDoubleReleaseCheck:] method may be used
|
2006-11-28 01:20:46 +00:00
|
|
|
|
* to turn on checking for retain/release errors in this method.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1999-12-13 12:14:01 +00:00
|
|
|
|
- (id) autorelease
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2011-05-28 15:28:24 +00:00
|
|
|
|
#if !GS_WITH_GC
|
1995-08-04 20:52:07 +00:00
|
|
|
|
if (double_release_check_enabled)
|
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
|
NSUInteger release_count;
|
|
|
|
|
NSUInteger retain_count = [self retainCount];
|
1995-08-04 20:52:07 +00:00
|
|
|
|
release_count = [autorelease_class autoreleaseCountForObject:self];
|
|
|
|
|
if (release_count > retain_count)
|
1996-03-26 19:35:47 +00:00
|
|
|
|
[NSException
|
|
|
|
|
raise: NSGenericException
|
|
|
|
|
format: @"Autorelease would release object too many times.\n"
|
1996-03-26 20:59:42 +00:00
|
|
|
|
@"%d release(s) versus %d retain(s)", release_count, retain_count];
|
1995-08-04 20:52:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-10-25 07:56:22 +00:00
|
|
|
|
(*autorelease_imp)(autorelease_class, autorelease_sel, self);
|
1999-01-28 17:21:03 +00:00
|
|
|
|
#endif
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Dummy method returning the receiver.
|
|
|
|
|
*/
|
2000-06-30 11:59:59 +00:00
|
|
|
|
+ (id) autorelease
|
1995-04-05 01:54:16 +00:00
|
|
|
|
{
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the receiver.
|
|
|
|
|
*/
|
1998-09-28 20:38:02 +00:00
|
|
|
|
+ (Class) class
|
|
|
|
|
{
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the hash of the receiver. Subclasses should ensure that their
|
|
|
|
|
* implementations of this method obey the rule that if the -isEqual: method
|
|
|
|
|
* returns YES for two instances of the class, the -hash method returns the
|
2004-08-11 05:24:55 +00:00
|
|
|
|
* same value for both instances.<br />
|
|
|
|
|
* The default implementation returns a value based on the address
|
|
|
|
|
* of the instance.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (NSUInteger) hash
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2004-08-11 05:24:55 +00:00
|
|
|
|
/*
|
|
|
|
|
* Ideally we would shift left to lose any zero bits produced by the
|
|
|
|
|
* alignment of the object in memory ... but that depends on the
|
|
|
|
|
* processor architecture and the memory allocatiion implementation.
|
|
|
|
|
* In the absence of detailed information, pick a reasonable value
|
|
|
|
|
* assuming the object will be aligned to an eight byte boundary.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
return (NSUInteger)(uintptr_t)self >> 3;
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Tests anObject and the receiver for equality. The default implementation
|
|
|
|
|
* considers two objects to be equal only if they are the same object
|
|
|
|
|
* (ie occupy the same memory location).<br />
|
|
|
|
|
* If a subclass overrides this method, it should also override the -hash
|
|
|
|
|
* method so that if two objects are equal they both have the same hash.
|
|
|
|
|
*/
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (BOOL) isEqual: (id)anObject
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
|
|
|
|
return (self == anObject);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns YES if aClass is the NSObject class
|
|
|
|
|
*/
|
1998-06-24 17:22:34 +00:00
|
|
|
|
+ (BOOL) isKindOfClass: (Class)aClass
|
|
|
|
|
{
|
1999-07-28 14:49:41 +00:00
|
|
|
|
if (aClass == [NSObject class])
|
|
|
|
|
return YES;
|
1998-06-24 17:22:34 +00:00
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns YES if the class of the receiver is either the same as aClass
|
|
|
|
|
* or is derived from (a subclass of) aClass.
|
|
|
|
|
*/
|
1995-03-12 15:40:22 +00:00
|
|
|
|
- (BOOL) isKindOfClass: (Class)aClass
|
|
|
|
|
{
|
2010-02-22 10:13:20 +00:00
|
|
|
|
Class class = object_getClass(self);
|
1995-03-12 15:40:22 +00:00
|
|
|
|
|
2000-10-31 16:17:33 +00:00
|
|
|
|
return GSObjCIsKindOf(class, aClass);
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns YES if aClass is the same as the receiving class.
|
|
|
|
|
*/
|
1998-06-24 17:22:34 +00:00
|
|
|
|
+ (BOOL) isMemberOfClass: (Class)aClass
|
|
|
|
|
{
|
2000-10-31 16:17:33 +00:00
|
|
|
|
return (self == aClass) ? YES : NO;
|
1998-06-24 17:22:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns YES if the class of the receiver is aClass
|
|
|
|
|
*/
|
1995-03-12 15:40:22 +00:00
|
|
|
|
- (BOOL) isMemberOfClass: (Class)aClass
|
|
|
|
|
{
|
2011-03-02 10:52:27 +00:00
|
|
|
|
return ([self class] == aClass) ? YES : NO;
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2002-08-14 07:36:25 +00:00
|
|
|
|
* Returns a flag to differentiate between 'true' objects, and objects
|
2002-06-01 08:55:19 +00:00
|
|
|
|
* which are proxies for other objects (ie they forward messages to the
|
|
|
|
|
* other objects).<br />
|
|
|
|
|
* The default implementation returns NO.
|
|
|
|
|
*/
|
1995-03-12 15:40:22 +00:00
|
|
|
|
- (BOOL) isProxy
|
|
|
|
|
{
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 14:24:54 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns YES if the receiver is aClass or a subclass of aClass.
|
|
|
|
|
*/
|
|
|
|
|
+ (BOOL) isSubclassOfClass: (Class)aClass
|
|
|
|
|
{
|
|
|
|
|
return GSObjCIsKindOf(self, aClass);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Causes the receiver to execute the method implementation corresponding
|
|
|
|
|
* to aSelector and returns the result.<br />
|
|
|
|
|
* The method must be one which takes no arguments and returns an object.
|
2002-08-27 17:02:05 +00:00
|
|
|
|
* <br />Raises NSInvalidArgumentException if given a null selector.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (id) performSelector: (SEL)aSelector
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
1998-10-26 12:14:12 +00:00
|
|
|
|
IMP msg;
|
|
|
|
|
|
|
|
|
|
if (aSelector == 0)
|
2002-08-27 17:02:05 +00:00
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2011-02-20 08:32:54 +00:00
|
|
|
|
msg = class_getMethodImplementation(object_getClass(self), aSelector);
|
1995-03-12 15:40:22 +00:00
|
|
|
|
if (!msg)
|
1996-03-26 20:59:42 +00:00
|
|
|
|
{
|
1998-10-26 12:14:12 +00:00
|
|
|
|
[NSException raise: NSGenericException
|
2003-08-24 23:07:41 +00:00
|
|
|
|
format: @"invalid selector passed to %s",
|
2010-02-22 10:13:20 +00:00
|
|
|
|
sel_getName(_cmd)];
|
1996-03-26 20:59:42 +00:00
|
|
|
|
return nil;
|
|
|
|
|
}
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return (*msg)(self, aSelector);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Causes the receiver to execute the method implementation corresponding
|
|
|
|
|
* to aSelector and returns the result.<br />
|
|
|
|
|
* The method must be one which takes one argument and returns an object.
|
2002-08-27 17:02:05 +00:00
|
|
|
|
* <br />Raises NSInvalidArgumentException if given a null selector.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (id) performSelector: (SEL)aSelector withObject: (id) anObject
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
1998-10-26 12:14:12 +00:00
|
|
|
|
IMP msg;
|
|
|
|
|
|
|
|
|
|
if (aSelector == 0)
|
2002-08-27 17:02:05 +00:00
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2011-02-20 08:32:54 +00:00
|
|
|
|
msg = class_getMethodImplementation(object_getClass(self), aSelector);
|
1995-03-12 15:40:22 +00:00
|
|
|
|
if (!msg)
|
1996-03-26 20:59:42 +00:00
|
|
|
|
{
|
1998-10-26 12:14:12 +00:00
|
|
|
|
[NSException raise: NSGenericException
|
2005-02-22 11:22:44 +00:00
|
|
|
|
format: @"invalid selector passed to %s",
|
2010-02-22 10:13:20 +00:00
|
|
|
|
sel_getName(_cmd)];
|
1996-03-26 20:59:42 +00:00
|
|
|
|
return nil;
|
|
|
|
|
}
|
1998-10-26 12:14:12 +00:00
|
|
|
|
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return (*msg)(self, aSelector, anObject);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Causes the receiver to execute the method implementation corresponding
|
|
|
|
|
* to aSelector and returns the result.<br />
|
|
|
|
|
* The method must be one which takes two arguments and returns an object.
|
2002-08-27 17:02:05 +00:00
|
|
|
|
* <br />Raises NSInvalidArgumentException if given a null selector.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (id) performSelector: (SEL)aSelector
|
|
|
|
|
withObject: (id) object1
|
|
|
|
|
withObject: (id) object2
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
1998-10-26 12:14:12 +00:00
|
|
|
|
IMP msg;
|
|
|
|
|
|
|
|
|
|
if (aSelector == 0)
|
2002-08-27 17:02:05 +00:00
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2011-02-20 08:32:54 +00:00
|
|
|
|
msg = class_getMethodImplementation(object_getClass(self), aSelector);
|
1995-03-12 15:40:22 +00:00
|
|
|
|
if (!msg)
|
1996-03-26 20:59:42 +00:00
|
|
|
|
{
|
1998-10-26 12:14:12 +00:00
|
|
|
|
[NSException raise: NSGenericException
|
2010-02-22 10:13:20 +00:00
|
|
|
|
format: @"invalid selector passed to %s", sel_getName(_cmd)];
|
1996-03-26 20:59:42 +00:00
|
|
|
|
return nil;
|
|
|
|
|
}
|
1998-10-26 12:14:12 +00:00
|
|
|
|
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return (*msg)(self, aSelector, object1, object2);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 05:08:10 +00:00
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* Decrements the retain count for the receiver if greater than zero,
|
2002-08-07 15:30:03 +00:00
|
|
|
|
* otherwise calls the dealloc method instead.<br />
|
2002-06-02 09:05:11 +00:00
|
|
|
|
* The default implementation calls the NSDecrementExtraRefCountWasZero()
|
|
|
|
|
* function to test the extra reference count for the receiver (and
|
|
|
|
|
* decrement it if non-zero) - if the extra reference count is zero then
|
|
|
|
|
* the retain count is one, and the dealloc method is called.<br />
|
|
|
|
|
* In GNUstep, the [NSObject+enableDoubleReleaseCheck:] method may be used
|
2002-08-07 15:30:03 +00:00
|
|
|
|
* to turn on checking for ratain/release errors in this method.
|
2002-06-01 05:08:10 +00:00
|
|
|
|
*/
|
1995-03-12 15:40:22 +00:00
|
|
|
|
- (oneway void) release
|
|
|
|
|
{
|
2011-05-28 14:51:40 +00:00
|
|
|
|
#if (GS_WITH_GC == 0)
|
1995-03-12 15:40:22 +00:00
|
|
|
|
if (NSDecrementExtraRefCountWasZero(self))
|
1999-12-15 17:31:01 +00:00
|
|
|
|
{
|
2011-06-29 13:13:15 +00:00
|
|
|
|
# ifdef OBJC_CAP_ARC
|
|
|
|
|
objc_delete_weak_refs(self);
|
|
|
|
|
# endif
|
2002-08-07 15:30:03 +00:00
|
|
|
|
[self dealloc];
|
1999-12-15 17:31:01 +00:00
|
|
|
|
}
|
1999-01-28 17:21:03 +00:00
|
|
|
|
#endif
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 05:08:10 +00:00
|
|
|
|
/**
|
|
|
|
|
* The class implementation of the release method is a dummy method
|
|
|
|
|
* having no effect. It is present so that class objects can be stored
|
|
|
|
|
* in containers (such as NSArray) which will send them retain and
|
|
|
|
|
* release messages.
|
|
|
|
|
*/
|
1995-04-05 01:54:16 +00:00
|
|
|
|
+ (oneway void) release
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a flag to say if the receiver will
|
|
|
|
|
* respond to the specified selector. This ignores situations
|
|
|
|
|
* where a subclass implements -forwardInvocation: to respond to
|
|
|
|
|
* selectors not normally handled ... in these cases the subclass
|
|
|
|
|
* may override this method to handle it.
|
2003-02-18 11:43:57 +00:00
|
|
|
|
* <br />If given a null selector, raises NSInvalidArgumentException when
|
|
|
|
|
* in MacOS-X compatibility more, or returns NO otherwise.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1995-03-12 15:40:22 +00:00
|
|
|
|
- (BOOL) respondsToSelector: (SEL)aSelector
|
|
|
|
|
{
|
2002-06-29 16:01:33 +00:00
|
|
|
|
if (aSelector == 0)
|
2003-02-18 11:43:57 +00:00
|
|
|
|
{
|
2006-10-20 10:56:27 +00:00
|
|
|
|
if (GSPrivateDefaultsFlag(GSMacOSXCompatible))
|
2003-02-18 11:43:57 +00:00
|
|
|
|
{
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%@ null selector given",
|
|
|
|
|
NSStringFromSelector(_cmd)];
|
|
|
|
|
}
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
2003-10-16 14:56:35 +00:00
|
|
|
|
|
2011-04-03 04:25:52 +00:00
|
|
|
|
return class_respondsToSelector(object_getClass(self), aSelector) ? YES : NO;
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 05:08:10 +00:00
|
|
|
|
/**
|
2002-06-02 09:05:11 +00:00
|
|
|
|
* Increments the reference count and returns the receiver.<br />
|
|
|
|
|
* The default implementation does this by calling NSIncrementExtraRefCount()
|
2002-06-01 05:08:10 +00:00
|
|
|
|
*/
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (id) retain
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2011-05-28 14:51:40 +00:00
|
|
|
|
#if (GS_WITH_GC == 0)
|
1995-03-24 20:09:36 +00:00
|
|
|
|
NSIncrementExtraRefCount(self);
|
1999-01-28 17:21:03 +00:00
|
|
|
|
#endif
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 05:08:10 +00:00
|
|
|
|
/**
|
|
|
|
|
* The class implementation of the retain method is a dummy method
|
|
|
|
|
* having no effect. It is present so that class objects can be stored
|
|
|
|
|
* in containers (such as NSArray) which will send them retain and
|
|
|
|
|
* release messages.
|
|
|
|
|
*/
|
2000-06-30 11:59:59 +00:00
|
|
|
|
+ (id) retain
|
1995-04-05 01:54:16 +00:00
|
|
|
|
{
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 05:08:10 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the reference count for the receiver. Each instance has an
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* implicit reference count of 1, and has an 'extra reference count'
|
2002-06-02 09:05:11 +00:00
|
|
|
|
* returned by the NSExtraRefCount() function, so the value returned by
|
|
|
|
|
* this method is always greater than zero.<br />
|
|
|
|
|
* By convention, objects which should (or can) never be deallocated
|
|
|
|
|
* return the maximum unsigned integer value.
|
2002-06-01 05:08:10 +00:00
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (NSUInteger) retainCount
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2011-05-28 14:51:40 +00:00
|
|
|
|
#if GS_WITH_GC
|
1999-01-28 17:21:03 +00:00
|
|
|
|
return UINT_MAX;
|
|
|
|
|
#else
|
1999-05-21 18:14:48 +00:00
|
|
|
|
return NSExtraRefCount(self) + 1;
|
1999-01-28 17:21:03 +00:00
|
|
|
|
#endif
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 05:08:10 +00:00
|
|
|
|
/**
|
|
|
|
|
* The class implementation of the retainCount method always returns
|
|
|
|
|
* the maximum unsigned integer value, as classes can not be deallocated
|
|
|
|
|
* the retain count mechanism is a dummy system for them.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
+ (NSUInteger) retainCount
|
1995-04-05 01:54:16 +00:00
|
|
|
|
{
|
|
|
|
|
return UINT_MAX;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* Returns the receiver.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (id) self
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the memory allocation zone in which the receiver is located.
|
|
|
|
|
*/
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (NSZone*) zone
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2011-05-25 11:15:08 +00:00
|
|
|
|
#if GS_WITH_GC || __OBJC_GC__
|
2010-03-05 09:30:18 +00:00
|
|
|
|
/* MacOS-X 10.5 seems to return the default malloc zone if GC is enabled.
|
|
|
|
|
*/
|
|
|
|
|
return NSDefaultMallocZone();
|
|
|
|
|
#else
|
|
|
|
|
return (((obj)self)[-1]).zone;
|
|
|
|
|
#endif
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-07-10 14:48:26 +00:00
|
|
|
|
#if !GS_WITH_GC && !__OBJC_GC__
|
|
|
|
|
+ (NSZone *) zone
|
|
|
|
|
{
|
|
|
|
|
return NSDefaultMallocZone();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Called to encode the instance variables of the receiver to aCoder.<br />
|
|
|
|
|
* Subclasses should call the superclass method at the start of their
|
|
|
|
|
* own implementation.
|
|
|
|
|
*/
|
1995-04-09 01:53:53 +00:00
|
|
|
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Called to intialise instance variables of the receiver from aDecoder.<br />
|
|
|
|
|
* Subclasses should call the superclass method at the start of their
|
|
|
|
|
* own implementation.
|
|
|
|
|
*/
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (id) initWithCoder: (NSCoder*)aDecoder
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-12 07:37:00 +00:00
|
|
|
|
+ (BOOL) resolveClassMethod: (SEL)name
|
1998-09-28 20:38:02 +00:00
|
|
|
|
{
|
2009-09-12 07:37:00 +00:00
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-23 09:42:18 +00:00
|
|
|
|
+ (BOOL) resolveInstanceMethod: (SEL)name
|
2009-09-12 07:37:00 +00:00
|
|
|
|
{
|
|
|
|
|
return NO;
|
1998-09-28 20:38:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* Sets the version number of the receiving class. Should be nonnegative.
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
+ (id) setVersion: (NSInteger)aVersion
|
1998-09-28 20:38:02 +00:00
|
|
|
|
{
|
1998-10-09 13:54:54 +00:00
|
|
|
|
if (aVersion < 0)
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%s +setVersion: may not set a negative version",
|
2003-08-24 23:07:41 +00:00
|
|
|
|
GSClassNameFromObject(self)];
|
A huge blob of changes to make -base build with libobjc2, without using the old libobjc2 headers.
Most of these changes involve simply removing direct manipulation of any runtime structures and replacing them with runtime function calls. For example class->name becomes class_getName(class) and so on.
libobjc2, like the Apple runtime, the NeXT runtime, and every version of the Objective-C spec, calls the class pointer in id isa. A few files now have #define class_pointer isa at the top. This line replaces class_pointer in the old GNU libobjc headers with isa so either class_pointer or isa can be used for accessing the class of an object. Note: object_getClass() should be used in most cases because, in some future version of the runtime, this will skip things like lock classes and other hidden classes (e.g. KVO classes).
All of the old forwarding stuff has been removed. Most of this stuff followed convoluted code paths that ended with an exception. A few simply broke in exciting ways. Hopefully no one has used them for the last ten years or so, but we can bring them back with some #ifndef stuff if they're really needed by anyone.
There is currently a bug in configure, which prevents dladdr() from being detected, so you need to manually tweak config.h to build - I have not fixed the fall-back code in objc-load.m to work with libobjc2, I just added a new version that uses the loader's functionality directly.
Although -base now builds, it builds with a lot of warnings. <string.h> is missing from a lot of files, so memcpy() and strlen() generate implicit function declaration warnings.
Additionally, libobjc2 does still provide the sel_{get,register}_*() functions, but they're wrappers around the newer API ones. These are deprecated and are not exposed in the headers. Although they work, we should be replacing them with the libobjc2 versions as soon as possible.
This incorporates a patch by Eric.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31265 72102866-910b-0410-8b05-ffd578937521
2010-09-09 15:06:09 +00:00
|
|
|
|
class_setVersion(self, aVersion);
|
1998-09-28 20:38:02 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-12 07:37:00 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the version number of the receiving class. This will default to
|
|
|
|
|
* a number assigned by the Objective C compiler if [NSObject -setVersion] has
|
|
|
|
|
* not been called.
|
|
|
|
|
*/
|
|
|
|
|
+ (NSInteger) version
|
2009-09-10 20:14:42 +00:00
|
|
|
|
{
|
A huge blob of changes to make -base build with libobjc2, without using the old libobjc2 headers.
Most of these changes involve simply removing direct manipulation of any runtime structures and replacing them with runtime function calls. For example class->name becomes class_getName(class) and so on.
libobjc2, like the Apple runtime, the NeXT runtime, and every version of the Objective-C spec, calls the class pointer in id isa. A few files now have #define class_pointer isa at the top. This line replaces class_pointer in the old GNU libobjc headers with isa so either class_pointer or isa can be used for accessing the class of an object. Note: object_getClass() should be used in most cases because, in some future version of the runtime, this will skip things like lock classes and other hidden classes (e.g. KVO classes).
All of the old forwarding stuff has been removed. Most of this stuff followed convoluted code paths that ended with an exception. A few simply broke in exciting ways. Hopefully no one has used them for the last ten years or so, but we can bring them back with some #ifndef stuff if they're really needed by anyone.
There is currently a bug in configure, which prevents dladdr() from being detected, so you need to manually tweak config.h to build - I have not fixed the fall-back code in objc-load.m to work with libobjc2, I just added a new version that uses the loader's functionality directly.
Although -base now builds, it builds with a lot of warnings. <string.h> is missing from a lot of files, so memcpy() and strlen() generate implicit function declaration warnings.
Additionally, libobjc2 does still provide the sel_{get,register}_*() functions, but they're wrappers around the newer API ones. These are deprecated and are not exposed in the headers. Although they work, we should be replacing them with the libobjc2 versions as soon as possible.
This incorporates a patch by Eric.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31265 72102866-910b-0410-8b05-ffd578937521
2010-09-09 15:06:09 +00:00
|
|
|
|
return class_getVersion(self);
|
2009-09-10 20:14:42 +00:00
|
|
|
|
}
|
2009-09-12 07:37:00 +00:00
|
|
|
|
|
|
|
|
|
- (id) autoContentAccessingProxy
|
2009-09-10 20:14:42 +00:00
|
|
|
|
{
|
2009-09-12 07:37:00 +00:00
|
|
|
|
return AUTORELEASE([[GSContentAccessingProxy alloc] initWithObject: self]);
|
2009-09-10 20:14:42 +00:00
|
|
|
|
}
|
2009-09-12 07:37:00 +00:00
|
|
|
|
|
2009-11-23 09:42:18 +00:00
|
|
|
|
- (id) forwardingTargetForSelector:(SEL)aSelector
|
2009-09-10 20:14:42 +00:00
|
|
|
|
{
|
2009-09-12 07:37:00 +00:00
|
|
|
|
return nil;
|
2009-09-10 20:14:42 +00:00
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
@end
|
|
|
|
|
|
1996-07-15 18:41:44 +00:00
|
|
|
|
|
2004-06-22 22:40:40 +00:00
|
|
|
|
/**
|
|
|
|
|
* Methods for compatibility with the NEXTSTEP (pre-OpenStep) 'Object' class.
|
|
|
|
|
*/
|
1995-03-12 15:40:22 +00:00
|
|
|
|
@implementation NSObject (NEXTSTEP)
|
|
|
|
|
|
|
|
|
|
/* NEXTSTEP Object class compatibility */
|
|
|
|
|
|
2004-06-22 22:40:40 +00:00
|
|
|
|
/**
|
|
|
|
|
* Logs a message. <em>Deprecated.</em> Use NSLog() in new code.
|
|
|
|
|
*/
|
2002-06-01 08:55:19 +00:00
|
|
|
|
- (id) error: (const char *)aString, ...
|
1995-01-26 17:55:52 +00:00
|
|
|
|
{
|
1995-03-12 15:40:22 +00:00
|
|
|
|
#define FMT "error: %s (%s)\n%s\n"
|
2003-08-24 23:07:41 +00:00
|
|
|
|
char fmt[(strlen((char*)FMT)+strlen((char*)GSClassNameFromObject(self))
|
1995-03-12 15:40:22 +00:00
|
|
|
|
+((aString!=NULL)?strlen((char*)aString):0)+8)];
|
|
|
|
|
va_list ap;
|
|
|
|
|
|
2011-03-07 15:34:06 +00:00
|
|
|
|
snprintf(fmt, sizeof(fmt), FMT, GSClassNameFromObject(self),
|
|
|
|
|
GSObjCIsInstance(self) ? "instance" : "class",
|
|
|
|
|
(aString != NULL) ? aString : "");
|
1995-03-12 15:40:22 +00:00
|
|
|
|
va_start(ap, aString);
|
2010-12-23 02:23:05 +00:00
|
|
|
|
vfprintf (stderr, fmt, ap);
|
|
|
|
|
abort ();
|
1995-03-12 15:40:22 +00:00
|
|
|
|
va_end(ap);
|
|
|
|
|
#undef FMT
|
2010-06-07 02:50:40 +00:00
|
|
|
|
return nil;
|
1995-01-26 17:55:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/*
|
1996-02-24 16:38:43 +00:00
|
|
|
|
- (const char *) name
|
1995-01-26 17:55:52 +00:00
|
|
|
|
{
|
2003-08-24 23:07:41 +00:00
|
|
|
|
return GSClassNameFromObject(self);
|
1995-01-26 17:55:52 +00:00
|
|
|
|
}
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1995-01-26 17:55:52 +00:00
|
|
|
|
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (BOOL) isKindOf: (Class)aClassObject
|
1995-01-26 17:55:52 +00:00
|
|
|
|
{
|
2000-06-30 11:59:59 +00:00
|
|
|
|
return [self isKindOfClass: aClassObject];
|
1995-01-26 17:55:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (BOOL) isMemberOf: (Class)aClassObject
|
1995-01-26 17:55:52 +00:00
|
|
|
|
{
|
2000-06-30 11:59:59 +00:00
|
|
|
|
return [self isMemberOfClass: aClassObject];
|
1995-01-26 17:55:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-06-30 11:59:59 +00:00
|
|
|
|
+ (BOOL) instancesRespondTo: (SEL)aSel
|
1995-01-26 17:55:52 +00:00
|
|
|
|
{
|
2000-06-30 11:59:59 +00:00
|
|
|
|
return [self instancesRespondToSelector: aSel];
|
1995-01-26 17:55:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (BOOL) respondsTo: (SEL)aSel
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2000-06-30 11:59:59 +00:00
|
|
|
|
return [self respondsToSelector: aSel];
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ (BOOL) conformsTo: (Protocol*)aProtocol
|
|
|
|
|
{
|
2000-06-30 11:59:59 +00:00
|
|
|
|
return [self conformsToProtocol: aProtocol];
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-03-27 17:25:42 +00:00
|
|
|
|
- (BOOL) conformsTo: (Protocol*)aProtocol
|
|
|
|
|
{
|
2000-06-30 11:59:59 +00:00
|
|
|
|
return [self conformsToProtocol: aProtocol];
|
1995-03-27 17:25:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-06-30 11:59:59 +00:00
|
|
|
|
+ (IMP) instanceMethodFor: (SEL)aSel
|
1995-01-26 17:55:52 +00:00
|
|
|
|
{
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return [self instanceMethodForSelector:aSel];
|
|
|
|
|
}
|
|
|
|
|
|
2000-06-28 09:35:12 +00:00
|
|
|
|
+ (NSMethodSignature*) instanceMethodSignatureForSelector: (SEL)aSelector
|
1997-09-01 21:59:51 +00:00
|
|
|
|
{
|
2002-08-27 17:02:05 +00:00
|
|
|
|
struct objc_method* mth;
|
|
|
|
|
|
|
|
|
|
if (aSelector == 0)
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
2004-08-20 17:53:16 +00:00
|
|
|
|
mth = GSGetMethod(self, aSelector, YES, YES);
|
2011-03-09 12:01:04 +00:00
|
|
|
|
if (0 == mth)
|
2006-05-15 12:07:35 +00:00
|
|
|
|
return nil;
|
2011-03-09 12:01:04 +00:00
|
|
|
|
return [NSMethodSignature
|
|
|
|
|
signatureWithObjCTypes: method_getTypeEncoding(mth)];
|
1997-09-01 21:59:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (IMP) methodFor: (SEL)aSel
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2000-06-30 11:59:59 +00:00
|
|
|
|
return [self methodForSelector: aSel];
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-06-30 11:59:59 +00:00
|
|
|
|
+ (id) poseAs: (Class)aClassObject
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2000-06-30 11:59:59 +00:00
|
|
|
|
[self poseAsClass: aClassObject];
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return self;
|
1995-01-26 17:55:52 +00:00
|
|
|
|
}
|
1995-03-12 15:40:22 +00:00
|
|
|
|
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (id) doesNotRecognize: (SEL)aSel
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
1996-03-26 20:59:42 +00:00
|
|
|
|
[NSException raise: NSGenericException
|
2002-01-31 15:41:47 +00:00
|
|
|
|
format: @"%s(%s) does not recognize %s",
|
2005-02-22 11:22:44 +00:00
|
|
|
|
GSClassNameFromObject(self),
|
2002-01-31 15:41:47 +00:00
|
|
|
|
GSObjCIsInstance(self) ? "instance" : "class",
|
2010-02-22 10:13:20 +00:00
|
|
|
|
aSel ? sel_getName(aSel) : "(null)"];
|
1996-03-26 20:59:42 +00:00
|
|
|
|
return nil;
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (id) perform: (SEL)sel with: (id)anObject
|
1995-03-23 03:31:30 +00:00
|
|
|
|
{
|
1998-09-28 20:38:02 +00:00
|
|
|
|
return [self performSelector:sel withObject:anObject];
|
1995-03-23 03:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (id) perform: (SEL)sel with: (id)anObject with: (id)anotherObject
|
1995-04-03 01:32:58 +00:00
|
|
|
|
{
|
2005-02-22 11:22:44 +00:00
|
|
|
|
return [self performSelector:sel withObject:anObject
|
1998-09-28 20:38:02 +00:00
|
|
|
|
withObject:anotherObject];
|
|
|
|
|
}
|
|
|
|
|
|
1995-03-12 15:40:22 +00:00
|
|
|
|
@end
|
|
|
|
|
|
1996-07-15 18:41:44 +00:00
|
|
|
|
|
2000-11-27 22:26:08 +00:00
|
|
|
|
|
2004-06-22 22:40:40 +00:00
|
|
|
|
/**
|
|
|
|
|
* Some non-standard extensions mainly needed for backwards compatibility
|
|
|
|
|
* and internal utility reasons.
|
|
|
|
|
*/
|
2004-04-16 23:21:26 +00:00
|
|
|
|
@implementation NSObject (GNUstep)
|
1995-03-12 15:40:22 +00:00
|
|
|
|
|
2002-06-01 08:55:19 +00:00
|
|
|
|
/**
|
|
|
|
|
* Enables runtime checking of retain/release/autorelease operations.<br />
|
2002-06-02 09:05:11 +00:00
|
|
|
|
* <p>Whenever either -autorelease or -release is called, the contents of any
|
2002-06-01 08:55:19 +00:00
|
|
|
|
* autorelease pools will be checked to see if there are more outstanding
|
|
|
|
|
* release operations than the objects retain count. In which case an
|
|
|
|
|
* exception is raised to say that the object is released too many times.
|
2002-06-02 09:05:11 +00:00
|
|
|
|
* </p>
|
|
|
|
|
* <p><strong>Beware</strong>, since this feature entails examining all active
|
|
|
|
|
* autorelease pools every time an object is released or autoreleased, it
|
|
|
|
|
* can cause a massive performance degradation ... it should only be enabled
|
|
|
|
|
* for debugging.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>
|
2002-10-27 01:38:30 +00:00
|
|
|
|
* When you are having memory allocation problems, it may make more sense
|
|
|
|
|
* to look at the memory allocation debugging functions documented in
|
|
|
|
|
* NSDebug.h, or use the NSZombie features.
|
2002-06-02 09:05:11 +00:00
|
|
|
|
* </p>
|
2002-06-01 08:55:19 +00:00
|
|
|
|
*/
|
1995-08-04 20:52:07 +00:00
|
|
|
|
+ (void) enableDoubleReleaseCheck: (BOOL)enable
|
|
|
|
|
{
|
|
|
|
|
double_release_check_enabled = enable;
|
|
|
|
|
}
|
|
|
|
|
|
2002-08-20 10:22:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* The default (NSObject) implementation of this method simply calls
|
|
|
|
|
* the -description method and discards the locale
|
|
|
|
|
* information.
|
|
|
|
|
*/
|
2011-02-23 11:52:17 +00:00
|
|
|
|
- (NSString*) descriptionWithLocale: (id)aLocale
|
2002-01-06 11:26:49 +00:00
|
|
|
|
{
|
|
|
|
|
return [self description];
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-23 11:52:17 +00:00
|
|
|
|
+ (NSString*) descriptionWithLocale: (id)aLocale
|
2002-01-06 11:26:49 +00:00
|
|
|
|
{
|
|
|
|
|
return [self description];
|
|
|
|
|
}
|
|
|
|
|
|
2002-08-20 10:22:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* The default (NSObject) implementation of this method simply calls
|
|
|
|
|
* the -descriptionWithLocale: method and discards the
|
|
|
|
|
* level information.
|
|
|
|
|
*/
|
2011-02-23 11:52:17 +00:00
|
|
|
|
- (NSString*) descriptionWithLocale: (id)aLocale
|
2009-02-23 20:42:32 +00:00
|
|
|
|
indent: (NSUInteger)level
|
2002-01-06 11:26:49 +00:00
|
|
|
|
{
|
|
|
|
|
return [self descriptionWithLocale: aLocale];
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-23 11:52:17 +00:00
|
|
|
|
+ (NSString*) descriptionWithLocale: (id)aLocale
|
2009-02-23 20:42:32 +00:00
|
|
|
|
indent: (NSUInteger)level
|
2002-01-06 11:26:49 +00:00
|
|
|
|
{
|
|
|
|
|
return [self descriptionWithLocale: aLocale];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL) _dealloc
|
|
|
|
|
{
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
|
|
|
|
|
2000-03-17 13:13:08 +00:00
|
|
|
|
- (BOOL) isMetaClass
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
2000-03-17 13:13:08 +00:00
|
|
|
|
- (BOOL) isClass
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2010-02-25 08:19:52 +00:00
|
|
|
|
return class_isMetaClass(object_getClass(self));
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-03-17 13:13:08 +00:00
|
|
|
|
- (BOOL) isMemberOfClassNamed: (const char*)aClassName
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
|
|
|
|
return ((aClassName!=NULL)
|
2010-02-22 10:13:20 +00:00
|
|
|
|
&&!strcmp(class_getName(object_getClass(self)), aClassName));
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-03-17 13:13:08 +00:00
|
|
|
|
+ (struct objc_method_description *) descriptionForInstanceMethod: (SEL)aSel
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2002-08-27 17:02:05 +00:00
|
|
|
|
if (aSel == 0)
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
|
|
|
|
|
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return ((struct objc_method_description *)
|
2004-08-20 17:53:16 +00:00
|
|
|
|
GSGetMethod(self, aSel, YES, YES));
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-03-17 13:13:08 +00:00
|
|
|
|
- (struct objc_method_description *) descriptionForMethod: (SEL)aSel
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2002-08-27 17:02:05 +00:00
|
|
|
|
if (aSel == 0)
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"%@ null selector given", NSStringFromSelector(_cmd)];
|
|
|
|
|
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return ((struct objc_method_description *)
|
2005-02-22 11:22:44 +00:00
|
|
|
|
GSGetMethod((GSObjCIsInstance(self)
|
2010-02-22 10:13:20 +00:00
|
|
|
|
? object_getClass(self) : (Class)self),
|
2004-08-20 17:53:16 +00:00
|
|
|
|
aSel,
|
|
|
|
|
GSObjCIsInstance(self),
|
|
|
|
|
YES));
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2010-09-08 09:00:15 +00:00
|
|
|
|
+ (NSInteger) streamVersion: (void*)aStream
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2010-09-08 09:00:15 +00:00
|
|
|
|
GSOnceMLog(@"[NSObject+streamVersion:] is deprecated ... do not use");
|
A huge blob of changes to make -base build with libobjc2, without using the old libobjc2 headers.
Most of these changes involve simply removing direct manipulation of any runtime structures and replacing them with runtime function calls. For example class->name becomes class_getName(class) and so on.
libobjc2, like the Apple runtime, the NeXT runtime, and every version of the Objective-C spec, calls the class pointer in id isa. A few files now have #define class_pointer isa at the top. This line replaces class_pointer in the old GNU libobjc headers with isa so either class_pointer or isa can be used for accessing the class of an object. Note: object_getClass() should be used in most cases because, in some future version of the runtime, this will skip things like lock classes and other hidden classes (e.g. KVO classes).
All of the old forwarding stuff has been removed. Most of this stuff followed convoluted code paths that ended with an exception. A few simply broke in exciting ways. Hopefully no one has used them for the last ten years or so, but we can bring them back with some #ifndef stuff if they're really needed by anyone.
There is currently a bug in configure, which prevents dladdr() from being detected, so you need to manually tweak config.h to build - I have not fixed the fall-back code in objc-load.m to work with libobjc2, I just added a new version that uses the loader's functionality directly.
Although -base now builds, it builds with a lot of warnings. <string.h> is missing from a lot of files, so memcpy() and strlen() generate implicit function declaration warnings.
Additionally, libobjc2 does still provide the sel_{get,register}_*() functions, but they're wrappers around the newer API ones. These are deprecated and are not exposed in the headers. Although they work, we should be replacing them with the libobjc2 versions as soon as possible.
This incorporates a patch by Eric.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31265 72102866-910b-0410-8b05-ffd578937521
2010-09-09 15:06:09 +00:00
|
|
|
|
return class_getVersion (self);
|
1995-03-12 15:40:22 +00:00
|
|
|
|
}
|
2010-09-08 09:00:15 +00:00
|
|
|
|
- (id) read: (void*)aStream
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2010-09-08 09:00:15 +00:00
|
|
|
|
GSOnceMLog(@"[NSObject-read:] is deprecated ... do not use");
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
2010-09-08 09:00:15 +00:00
|
|
|
|
- (id) write: (void*)aStream
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2010-09-08 09:00:15 +00:00
|
|
|
|
GSOnceMLog(@"[NSObject-write:] is deprecated ... do not use");
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
2000-06-30 11:59:59 +00:00
|
|
|
|
- (id) awake
|
1995-03-12 15:40:22 +00:00
|
|
|
|
{
|
2010-09-08 09:00:15 +00:00
|
|
|
|
GSOnceMLog(@"[NSObject-awake] is deprecated ... do not use");
|
1995-03-12 15:40:22 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
1998-11-12 10:58:17 +00:00
|
|
|
|
|
2002-03-27 09:55:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@implementation NSZombie
|
2010-01-11 11:23:03 +00:00
|
|
|
|
- (Class) class
|
|
|
|
|
{
|
2011-03-09 12:01:04 +00:00
|
|
|
|
return object_getClass(self);
|
2010-01-11 11:23:03 +00:00
|
|
|
|
}
|
2009-12-20 16:59:41 +00:00
|
|
|
|
- (Class) originalClass
|
2005-07-08 11:48:37 +00:00
|
|
|
|
{
|
2011-06-20 07:33:27 +00:00
|
|
|
|
return zombieMap ? NSMapGet(zombieMap, (void*)self) : Nil;
|
2005-07-08 11:48:37 +00:00
|
|
|
|
}
|
2002-03-27 09:55:57 +00:00
|
|
|
|
- (void) forwardInvocation: (NSInvocation*)anInvocation
|
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
|
NSUInteger size = [[anInvocation methodSignature] methodReturnLength];
|
2002-03-27 09:55:57 +00:00
|
|
|
|
unsigned char v[size];
|
|
|
|
|
|
|
|
|
|
memset(v, '\0', size);
|
|
|
|
|
GSLogZombie(self, [anInvocation selector]);
|
|
|
|
|
[anInvocation setReturnValue: (void*)v];
|
|
|
|
|
return;
|
|
|
|
|
}
|
2003-07-23 21:42:03 +00:00
|
|
|
|
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
|
|
|
|
|
{
|
|
|
|
|
Class c;
|
|
|
|
|
|
2010-08-17 18:36:46 +00:00
|
|
|
|
if (0 == aSelector)
|
|
|
|
|
{
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
2009-09-10 20:14:42 +00:00
|
|
|
|
[allocationLock lock];
|
2011-06-20 07:33:27 +00:00
|
|
|
|
c = zombieMap ? NSMapGet(zombieMap, (void*)self) : Nil;
|
2009-09-10 20:14:42 +00:00
|
|
|
|
[allocationLock unlock];
|
2003-07-23 21:42:03 +00:00
|
|
|
|
return [c instanceMethodSignatureForSelector: aSelector];
|
|
|
|
|
}
|
2002-03-27 09:55:57 +00:00
|
|
|
|
@end
|
|
|
|
|
|
2011-05-26 18:37:58 +00:00
|
|
|
|
@implementation GSContentAccessingProxy
|
2009-09-12 07:37:00 +00:00
|
|
|
|
- (void) dealloc
|
2009-09-10 20:14:42 +00:00
|
|
|
|
{
|
2009-09-12 07:37:00 +00:00
|
|
|
|
[object endContentAccess];
|
|
|
|
|
[super dealloc];
|
2009-09-10 20:14:42 +00:00
|
|
|
|
}
|
2009-09-12 07:37:00 +00:00
|
|
|
|
|
|
|
|
|
- (void) finalize
|
2009-09-10 20:14:42 +00:00
|
|
|
|
{
|
2009-09-12 07:37:00 +00:00
|
|
|
|
[object endContentAccess];
|
2009-09-10 20:14:42 +00:00
|
|
|
|
}
|
2009-09-12 07:37:00 +00:00
|
|
|
|
|
|
|
|
|
- (id) forwardingTargetForSelector: (SEL)aSelector
|
2009-09-10 20:14:42 +00:00
|
|
|
|
{
|
2009-09-12 07:37:00 +00:00
|
|
|
|
return object;
|
2009-09-10 20:14:42 +00:00
|
|
|
|
}
|
|
|
|
|
/* Support for legacy runtimes... */
|
|
|
|
|
- (void) forwardInvocation: (NSInvocation*)anInvocation
|
|
|
|
|
{
|
2009-09-12 07:37:00 +00:00
|
|
|
|
[anInvocation invokeWithTarget: object];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (id) initWithObject: (id)anObject
|
|
|
|
|
{
|
|
|
|
|
ASSIGN(object, anObject);
|
|
|
|
|
[object beginContentAccess];
|
|
|
|
|
return self;
|
2009-09-10 20:14:42 +00:00
|
|
|
|
}
|
2009-09-12 07:37:00 +00:00
|
|
|
|
|
2009-09-10 20:14:42 +00:00
|
|
|
|
- (NSMethodSignature*) methodSignatureForSelector: (SEL)aSelector
|
|
|
|
|
{
|
2009-09-12 07:37:00 +00:00
|
|
|
|
return [object methodSignatureForSelector: aSelector];
|
2009-09-10 20:14:42 +00:00
|
|
|
|
}
|
|
|
|
|
@end
|
2011-02-10 10:52:54 +00:00
|
|
|
|
|