mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
some small fixups
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@36616 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
891d7e0f24
commit
360e1f6ec6
5 changed files with 66 additions and 66 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2013-05-13 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/ObjectiveC2/runtime.c: when replacing a method, update the
|
||||
cache so we don't use the old version.
|
||||
* Source/NSNotificationCenter.m: trivial tweak to map release code
|
||||
and remove method caching for OSX compatibility :-(
|
||||
* Source/NSPropertyList.m: Fix bug byte swapping unicode in apple
|
||||
binary plist generation.
|
||||
* Tests/base/NSNotification/dynamic.m: Fix crash in testcase.
|
||||
|
||||
2013-05-13 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSURLConnection.m: Release delegate immediately after
|
||||
|
|
|
@ -155,7 +155,6 @@ struct NCTbl; /* Notification Center Table structure */
|
|||
@public
|
||||
__weak id observer; /* Object to receive message. */
|
||||
SEL selector; /* Method selector. */
|
||||
IMP method; /* Method implementation. */
|
||||
struct Obs *next; /* Next item in linked list. */
|
||||
struct NCTbl *link; /* Pointer back to chunk table */
|
||||
}
|
||||
|
@ -169,7 +168,6 @@ struct NCTbl; /* Notification Center Table structure */
|
|||
typedef struct Obs {
|
||||
id observer; /* Object to receive message. */
|
||||
SEL selector; /* Method selector. */
|
||||
IMP method; /* Method implementation. */
|
||||
struct Obs *next; /* Next item in linked list. */
|
||||
int retained; /* Retain count for structure. */
|
||||
struct NCTbl *link; /* Pointer back to chunk table */
|
||||
|
@ -248,8 +246,7 @@ static void obsFree(Observation *o);
|
|||
#include "GNUstepBase/GSIArray.h"
|
||||
|
||||
#define GSI_MAP_RETAIN_KEY(M, X)
|
||||
#define GSI_MAP_RELEASE_KEY(M, X) ({if ((((uintptr_t)X.obj) & 1) == 0) \
|
||||
RELEASE(X.obj);})
|
||||
#define GSI_MAP_RELEASE_KEY(M, X) ({if (YES == M->extra) RELEASE(X.obj);})
|
||||
#define GSI_MAP_HASH(M, X) doHash(X.obj)
|
||||
#define GSI_MAP_EQUAL(M, X,Y) doEqual(X.obj, Y.obj)
|
||||
#define GSI_MAP_RETAIN_VAL(M, X)
|
||||
|
@ -258,7 +255,7 @@ static void obsFree(Observation *o);
|
|||
#define GSI_MAP_KTYPES GSUNION_OBJ|GSUNION_NSINT
|
||||
#define GSI_MAP_VTYPES GSUNION_PTR
|
||||
#define GSI_MAP_VEXTRA Observation*
|
||||
#define GSI_MAP_EXTRA void*
|
||||
#define GSI_MAP_EXTRA BOOL
|
||||
|
||||
#if GS_WITH_GC
|
||||
#include <gc/gc_typed.h>
|
||||
|
@ -313,7 +310,7 @@ typedef struct NCTbl {
|
|||
#define LOCKCOUNT (TABLE->lockCount)
|
||||
|
||||
static Observation *
|
||||
obsNew(NCTable *t, SEL s, IMP m, id o)
|
||||
obsNew(NCTable *t, SEL s, id o)
|
||||
{
|
||||
Observation *obs;
|
||||
|
||||
|
@ -373,7 +370,6 @@ obsNew(NCTable *t, SEL s, IMP m, id o)
|
|||
#endif
|
||||
|
||||
obs->selector = s;
|
||||
obs->method = m;
|
||||
#if GS_WITH_GC
|
||||
GSAssignZeroingWeakPointer((void**)&obs->observer, (void*)o);
|
||||
#else
|
||||
|
@ -490,6 +486,7 @@ static NCTable *newNCTable(void)
|
|||
t->named = NSAllocateCollectable(sizeof(GSIMapTable_t), NSScannedOption);
|
||||
GSIMapInitWithZoneAndCapacity(t->nameless, _zone, 16);
|
||||
GSIMapInitWithZoneAndCapacity(t->named, _zone, 128);
|
||||
t->named->extra = YES; // This table retains keys
|
||||
|
||||
t->_lock = [NSRecursiveLock new];
|
||||
return t;
|
||||
|
@ -651,10 +648,6 @@ purgeCollectedFromMapNode(GSIMapTable map, GSIMapNode node)
|
|||
* extra bit. This should be ok for the objects we deal with
|
||||
* which are all aligned on 4 or 8 byte boundaries on all the machines
|
||||
* I know of.
|
||||
*
|
||||
* We also use this trick to differentiate between map table keys that
|
||||
* should be treated as objects (notification names) and those that
|
||||
* should be treated as pointers (notification objects)
|
||||
*/
|
||||
#define CHEATGC(X) (id)(((uintptr_t)X) | 1)
|
||||
|
||||
|
@ -795,9 +788,6 @@ static NSNotificationCenter *default_center = nil;
|
|||
name: (NSString*)name
|
||||
object: (id)object
|
||||
{
|
||||
Class cls;
|
||||
Method method;
|
||||
IMP imp;
|
||||
Observation *list;
|
||||
Observation *o;
|
||||
GSIMapTable m;
|
||||
|
@ -811,28 +801,17 @@ static NSNotificationCenter *default_center = nil;
|
|||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Null selector passed to addObserver ..."];
|
||||
|
||||
cls = object_getClass(observer);
|
||||
method = class_getInstanceMethod(cls, selector);
|
||||
imp = method_getImplementation(method);
|
||||
if (0 == imp)
|
||||
if ([observer respondsToSelector: selector] == NO)
|
||||
{
|
||||
/* A class may not implement the selector (in which case we can't
|
||||
* cache the method), but if it's going to forward the message to
|
||||
* some other object it must at least say it responds to the
|
||||
* selector.
|
||||
*/
|
||||
if ([observer respondsToSelector: selector] == NO)
|
||||
{
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"[%@-%@] Observer '%@' does not respond to selector '%@'",
|
||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd),
|
||||
observer, NSStringFromSelector(selector)];
|
||||
}
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"[%@-%@] Observer '%@' does not respond to selector '%@'",
|
||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd),
|
||||
observer, NSStringFromSelector(selector)];
|
||||
}
|
||||
|
||||
lockNCTable(TABLE);
|
||||
|
||||
o = obsNew(TABLE, selector, imp, observer);
|
||||
o = obsNew(TABLE, selector, observer);
|
||||
|
||||
if (object != nil)
|
||||
{
|
||||
|
@ -1231,15 +1210,8 @@ static NSNotificationCenter *default_center = nil;
|
|||
{
|
||||
NS_DURING
|
||||
{
|
||||
if (0 == o->method)
|
||||
{
|
||||
[o->observer performSelector: o->selector
|
||||
withObject: notification];
|
||||
}
|
||||
else
|
||||
{
|
||||
(*o->method)(o->observer, o->selector, notification);
|
||||
}
|
||||
[o->observer performSelector: o->selector
|
||||
withObject: notification];
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
|
|
|
@ -3723,18 +3723,20 @@ isEqualFunc(const void *item1, const void *item2,
|
|||
buffer = [dest mutableBytes] + offset;
|
||||
[string getCharacters: buffer];
|
||||
|
||||
// Always store in big-endian, so if machine is little-endian,
|
||||
// perform byte-swapping.
|
||||
|
||||
#if !GS_WORDS_BIGENDIAN
|
||||
/* Always store in big-endian, so if machine is little-endian,
|
||||
* perform byte-swapping.
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
uint8_t *o = (uint8_t*)buffer;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
uint8_t o = *buffer++;
|
||||
uint8_t c = *o++;
|
||||
|
||||
buffer[-1] = *buffer;
|
||||
*buffer++ = o;
|
||||
o[-1] = *o;
|
||||
*o++ = c;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -575,16 +575,22 @@ IMP
|
|||
class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)
|
||||
{
|
||||
Method method = class_getInstanceMethodNonrecursive(cls, name);
|
||||
IMP old;
|
||||
|
||||
if (method == NULL)
|
||||
{
|
||||
class_addMethod(cls, name, imp, types);
|
||||
return NULL;
|
||||
}
|
||||
old = (IMP) method->method_imp;
|
||||
method->method_imp = (objc_imp_gnu) imp;
|
||||
return old;
|
||||
else
|
||||
{
|
||||
IMP old = (IMP) method->method_imp;
|
||||
method->method_imp = (objc_imp_gnu) imp;
|
||||
if (CLS_ISRESOLV(cls))
|
||||
{
|
||||
__objc_update_dispatch_table_for_class(cls);
|
||||
}
|
||||
return old;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,26 +2,36 @@
|
|||
#include <objc/runtime.h>
|
||||
#import "ObjectTesting.h"
|
||||
|
||||
@interface Toggle : NSObject @end
|
||||
static BOOL notifiedCurrent = NO;
|
||||
|
||||
@interface Toggle : NSObject
|
||||
@end
|
||||
|
||||
@implementation Toggle
|
||||
- (void)foo: (NSNotification*)n
|
||||
- (void) foo: (NSNotification*)n
|
||||
{
|
||||
assert(0);
|
||||
notifiedCurrent = NO;
|
||||
}
|
||||
- (void) bar: (NSNotification*)n
|
||||
{
|
||||
notifiedCurrent = YES;
|
||||
}
|
||||
- (void)bar: (NSNotification*)n {}
|
||||
@end
|
||||
|
||||
int main(void)
|
||||
{
|
||||
[NSAutoreleasePool new];
|
||||
NSNotificationCenter *nc = [NSNotificationCenter new];
|
||||
id t = [Toggle new];
|
||||
[nc addObserver: t selector: @selector(foo:) name: nil object: nil];
|
||||
class_replaceMethod([Toggle class],
|
||||
@selector(foo:),
|
||||
class_getMethodImplementation([Toggle class],
|
||||
@selector(bar:)),
|
||||
"v@:@");
|
||||
[nc postNotificationName: @"foo" object: t];
|
||||
return 0;
|
||||
NSNotificationCenter *nc;
|
||||
id t = [Toggle new];
|
||||
|
||||
[NSAutoreleasePool new];
|
||||
nc = [NSNotificationCenter new];
|
||||
[nc addObserver: t selector: @selector(foo:) name: nil object: nil];
|
||||
class_replaceMethod([Toggle class],
|
||||
@selector(foo:),
|
||||
class_getMethodImplementation([Toggle class], @selector(bar:)),
|
||||
"v@:@");
|
||||
[nc postNotificationName: @"foo" object: t];
|
||||
[t release];
|
||||
PASS(YES == notifiedCurrent, "implementation not cached");
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue