Avoid crashing on non-fatal Objective-C exceptions caused by a 10.4-only Apple bug. b=461381 r=josh sr=roc

This commit is contained in:
Steven Michaud 2008-12-10 15:42:00 -06:00
Родитель 19a3b09f74
Коммит bcf4768b4e
2 изменённых файлов: 34 добавлений и 8 удалений

Просмотреть файл

@ -88,14 +88,19 @@ nsMenuX::nsMenuX()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
if (nsToolkit::OnLeopardOrLater() && !gMenuMethodsSwizzled) {
nsToolkit::SwizzleMethods([NSMenu class], @selector(_addItem:toTable:),
@selector(nsMenuX_NSMenu_addItem:toTable:), PR_TRUE);
nsToolkit::SwizzleMethods([NSMenu class], @selector(_removeItem:fromTable:),
@selector(nsMenuX_NSMenu_removeItem:fromTable:), PR_TRUE);
Class SCTGRLIndexClass = ::NSClassFromString(@"SCTGRLIndex");
nsToolkit::SwizzleMethods(SCTGRLIndexClass, @selector(indexMenuBarDynamically),
@selector(nsMenuX_SCTGRLIndex_indexMenuBarDynamically));
if (!gMenuMethodsSwizzled) {
if (nsToolkit::OnLeopardOrLater()) {
nsToolkit::SwizzleMethods([NSMenu class], @selector(_addItem:toTable:),
@selector(nsMenuX_NSMenu_addItem:toTable:), PR_TRUE);
nsToolkit::SwizzleMethods([NSMenu class], @selector(_removeItem:fromTable:),
@selector(nsMenuX_NSMenu_removeItem:fromTable:), PR_TRUE);
Class SCTGRLIndexClass = ::NSClassFromString(@"SCTGRLIndex");
nsToolkit::SwizzleMethods(SCTGRLIndexClass, @selector(indexMenuBarDynamically),
@selector(nsMenuX_SCTGRLIndex_indexMenuBarDynamically));
} else {
nsToolkit::SwizzleMethods([NSMenu class], @selector(performKeyEquivalent:),
@selector(nsMenuX_NSMenu_performKeyEquivalent:));
}
gMenuMethodsSwizzled = PR_TRUE;
}
@ -1120,6 +1125,7 @@ static NSMutableDictionary *gShadowKeyEquivDB = nil;
@interface NSMenu (MethodSwizzling)
+ (void)nsMenuX_NSMenu_addItem:(NSMenuItem *)aItem toTable:(NSMapTable *)aTable;
+ (void)nsMenuX_NSMenu_removeItem:(NSMenuItem *)aItem fromTable:(NSMapTable *)aTable;
- (BOOL)nsMenuX_NSMenu_performKeyEquivalent:(NSEvent *)theEvent;
@end
@implementation NSMenu (MethodSwizzling)
@ -1165,6 +1171,20 @@ static NSMutableDictionary *gShadowKeyEquivDB = nil;
NS_OBJC_END_TRY_ABORT_BLOCK;
}
- (BOOL)nsMenuX_NSMenu_performKeyEquivalent:(NSEvent *)theEvent
{
// On OS X 10.4.X (Tiger), Objective-C exceptions can occur during calls to
// [NSMenu performKeyEquivalent:] (from [GeckoNSMenu performKeyEquivalent:]
// or otherwise) that shouldn't be fatal (see bmo bug 461381). So on Tiger
// we hook this system call to eat (and log) all Objective-C exceptions that
// occur during its execution. Since we don't call XPCOM code from here,
// this will never cause XPCOM objects to be left on the stack without
// cleanup.
NS_OBJC_BEGIN_TRY_LOGONLY_BLOCK_RETURN;
return [self nsMenuX_NSMenu_performKeyEquivalent:theEvent];
NS_OBJC_END_TRY_LOGONLY_BLOCK_RETURN(NO);
}
@end
// This class is needed to keep track of when the OS is (re)indexing all of

Просмотреть файл

@ -240,4 +240,10 @@ NS_OBJC_TRY(_e, )
nsObjCExceptionLog(_exn); \
}
#define NS_OBJC_BEGIN_TRY_LOGONLY_BLOCK_RETURN @try {
#define NS_OBJC_END_TRY_LOGONLY_BLOCK_RETURN(_rv) } @catch(NSException *_exn) { \
nsObjCExceptionLog(_exn); \
} \
return _rv;
#endif // nsObjCExceptions_h_