From d05bb0584e442723756ad34f2e556fc9b6a7715d Mon Sep 17 00:00:00 2001 From: CaS Date: Mon, 28 Feb 2005 17:18:54 +0000 Subject: [PATCH] Fix fosdem changes and a few bugs exposed by them. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@20811 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 17 ++++++++ Source/NSAutoreleasePool.m | 50 +++++++++++++++-------- Source/NSCharacterSet.m | 83 ++++++++++++++++++++++++++++++++------ Source/NSProxy.m | 15 +++++++ 4 files changed, 136 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 87910c643..49319cd12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2005-02-28 17:10 Richard Frith-Macdonald + + * Source/NSAutoreleasePool.m: + * Source/NSCharacterSet.m: + * Source/NSproxy.m: + Damn ... when I ran the testsuite for the stuff I did at fosdem, it + all worked ... but now I find that it was linking to an older version + of the base library and actually the changes were broken. + The new modifications should (hopefully) fix all breakage. + The changes exposed rare bugs in the existing code ... + NSCharacterSet was returning immutable copies of the standard + character sets when it should return mutable ones, it was also + being a bit bad about allocating new instances. NSProxy was + failing to implement instanceMethodForSelector:, and NSAutoreleasePool + had a bug which could mess up a bit if the objects being deallocated + by it autoreleased anything. + 2005-02-28 David Ayers * Source/NSPropertyList.m (OAppend): Attempt to transform diff --git a/Source/NSAutoreleasePool.m b/Source/NSAutoreleasePool.m index 2bcbbd098..04ab13737 100644 --- a/Source/NSAutoreleasePool.m +++ b/Source/NSAutoreleasePool.m @@ -327,14 +327,35 @@ static IMP initImp; - (void) dealloc { + struct autorelease_thread_vars *tv = ARP_THREAD_VARS; + + /* + * Remove self from the linked list of pools in use. + * Do this *first* so that any object which does an autorelease while + * being released does not cause an object to be added to this pool! + */ + if (tv->current_pool == self) + { + tv->current_pool = _parent; + if (_parent != nil) + { + _parent->_child = nil; + } + } + // fprintf (stderr, "Deallocating an NSAutoreleasePool\n"); /* If there are NSAutoreleasePool below us in the stack of NSAutoreleasePools, then deallocate them also. The (only) way we could get in this situation (in correctly written programs, that don't release NSAutoreleasePools in weird ways), is if an exception threw us up the stack. */ - if (_child) - [_child dealloc]; + if (_child != nil) + { + NSAutoreleasePool *child = _child; + + _child = nil; + [child dealloc]; + } /* Make debugging easier by checking to see if the user already dealloced the object before trying to release it. Also, take the @@ -366,7 +387,14 @@ static IMP initImp; if (classes[hash] != c) { classes[hash] = c; - imps[hash] = [c methodForSelector: releaseSel]; + if (GSObjCIsInstance(anObject)) + { + imps[hash] = [c instanceMethodForSelector: releaseSel]; + } + else + { + imps[hash] = [c methodForSelector: releaseSel]; + } } (imps[hash])(anObject, releaseSel); } @@ -375,20 +403,8 @@ static IMP initImp; } } - { - struct autorelease_thread_vars *tv; - NSAutoreleasePool **cp; - - /* Uninstall ourselves as the current pool; install our parent pool. */ - tv = ARP_THREAD_VARS; - cp = &(tv->current_pool); - *cp = _parent; - if (*cp) - (*cp)->_child = nil; - - /* Don't deallocate ourself, just save us for later use. */ - push_pool_to_cache (tv, self); - } + /* Don't deallocate ourself, just save us for later use. */ + push_pool_to_cache (tv, self); } - (void) emptyPool diff --git a/Source/NSCharacterSet.m b/Source/NSCharacterSet.m index c32b83819..78e02dd21 100644 --- a/Source/NSCharacterSet.m +++ b/Source/NSCharacterSet.m @@ -106,15 +106,6 @@ static Class abstractClass = nil; cache_lock = [GSLazyLock new]; } -/* Provide a default object for allocation */ -+ (id) allocWithZone: (NSZone*)zone -{ - if (self == abstractClass) - return NSAllocateObject([NSBitmapCharSet self], 0, zone); - else - return NSAllocateObject(self, 0, zone); -} - /** * Creat and cache (or retrieve from cache) a characterset * using static bitmap data. @@ -356,7 +347,7 @@ static Class abstractClass = nil; - (id) initWithCoder: (NSCoder*)aCoder { - if ([self class] == [NSCharacterSet class]) + if ([self class] == abstractClass) { int index; @@ -365,7 +356,10 @@ static Class abstractClass = nil; */ DESTROY(self); [aCoder decodeValueOfObjCType: @encode(int) at: &index]; - self = RETAIN([NSCharacterSet _staticSet: 0 number: index]); + self = RETAIN([abstractClass _staticSet: 0 number: index]); + } + else + { } return self; } @@ -374,7 +368,7 @@ static Class abstractClass = nil; { if (anObject == self) return YES; - if ([anObject isKindOfClass: [NSCharacterSet class]]) + if ([anObject isKindOfClass: abstractClass]) { unsigned i; @@ -448,6 +442,71 @@ static Class abstractClass = nil; return AUTORELEASE([[NSMutableBitmapCharSet alloc] initWithBitmap: data]); } ++ (NSCharacterSet*) alphanumericCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) controlCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) decimalDigitCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) decomposableCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) illegalCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) letterCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) lowercaseLetterCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) nonBaseCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) punctuationCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) symbolAndOperatorCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) uppercaseLetterCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) whitespaceAndNewlineCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + ++ (NSCharacterSet*) whitespaceCharacterSet +{ + return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]); +} + /* Mutable subclasses must implement ALL of these methods. */ /** diff --git a/Source/NSProxy.m b/Source/NSProxy.m index ad5db8ebe..d06ed650d 100644 --- a/Source/NSProxy.m +++ b/Source/NSProxy.m @@ -102,6 +102,17 @@ extern BOOL __objc_responds_to(id, SEL); return [NSString stringWithFormat: @"<%s>", GSClassNameFromObject(self)]; } ++ (IMP) instanceMethodForSelector: (SEL)aSelector +{ + if (aSelector == 0) + [NSException raise: NSInvalidArgumentException + format: @"%@ null selector given", NSStringFromSelector(_cmd)]; + /* + * Since 'self' is an class, get_imp() will get the instance method. + */ + return get_imp((Class)self, aSelector); +} + /** * Returns NO ... the NSProxy class cannot be an instance of any class. */ @@ -128,6 +139,10 @@ extern BOOL __objc_responds_to(id, SEL); - (IMP) methodForSelector: (SEL)aSelector { + if (aSelector == 0) + [NSException raise: NSInvalidArgumentException + format: @"%@ null selector given", NSStringFromSelector(_cmd)]; + return get_imp(GSObjCClass((id)self), aSelector); }