WebDelegateImplementationCaching.mm   [plain text]

/*
* Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 David Smith (catfish.man@gmail.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#import "WebDelegateImplementationCaching.h"

#import "WebKitLogging.h"
#import "WebView.h"
#import "WebViewData.h"
#import <wtf/ObjCRuntimeExtras.h>

#if PLATFORM(IOS_FAMILY)
#import "WebViewInternal.h"
#import <WebCore/WebCoreThreadMessage.h>
#endif

@implementation WebView (WebDelegateImplementationCaching)

WebResourceDelegateImplementationCache* WebViewGetResourceLoadDelegateImplementations(WebView *webView)
{
static WebResourceDelegateImplementationCache empty;
if (!webView)
return &empty;
return &webView->_private->resourceLoadDelegateImplementations;
}

WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementations(WebView *webView)
{
static WebFrameLoadDelegateImplementationCache empty;
if (!webView)
return &empty;
return &webView->_private->frameLoadDelegateImplementations;
}

WebScriptDebugDelegateImplementationCache* WebViewGetScriptDebugDelegateImplementations(WebView *webView)
{
static WebScriptDebugDelegateImplementationCache empty;
if (!webView)
return &empty;
return &webView->_private->scriptDebugDelegateImplementations;
}

WebHistoryDelegateImplementationCache* WebViewGetHistoryDelegateImplementations(WebView *webView)
{
static WebHistoryDelegateImplementationCache empty;
if (!webView)
return &empty;
return &webView->_private->historyDelegateImplementations;
}

// We use these functions to call the delegates and block exceptions. These functions are
// declared inside a WebView category to get direct access to the delegate data memebers,
// preventing more ObjC message dispatch and compensating for the expense of the @try/@catch.

typedef float (*ObjCMsgSendFPRet)(id, SEL, ...);
#if !PLATFORM(IOS_FAMILY)
static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend);
#endif

static inline id CallDelegate(WebView *self, id delegate, SEL selector)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return nil;
@try {
return wtfObjCMsgSend<id>(delegate, selector, self);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return nil;
@try {
return wtfObjCMsgSend<id>(delegate, selector, self, object);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object atIndex:3];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

static inline id CallDelegate(WebView *self, id delegate, SEL selector, NSRect rect)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return nil;
@try {
return wtfObjCMsgSend<id>(delegate, selector, self, rect);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&rect atIndex:3];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return nil;
@try {
return wtfObjCMsgSend<id>(delegate, selector, self, object1, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object1 atIndex:3];
[invocation setArgument:&object2 atIndex:4];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, BOOL boolean)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return nil;
@try {
return wtfObjCMsgSend<id>(delegate, selector, self, object, boolean);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object atIndex:3];
[invocation setArgument:&boolean atIndex:4];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return nil;
@try {
return wtfObjCMsgSend<id>(delegate, selector, self, object1, object2, object3);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object1 atIndex:3];
[invocation setArgument:&object2 atIndex:4];
[invocation setArgument:&object3 atIndex:5];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, NSUInteger integer)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return nil;
@try {
return wtfObjCMsgSend<id>(delegate, selector, self, object, integer);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object atIndex:3];
[invocation setArgument:&integer atIndex:4];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

static inline float CallDelegateReturningFloat(WebView *self, id delegate, SEL selector)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return 0.0f;
@try {
return objc_msgSend_float_return(delegate, selector, self);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return 0.0f;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return 0.0f;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];

float returnValue = 0.0f;
@try {
WebThreadCallDelegate(invocation);
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return 0.0f;
#endif
}

static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return result;
@try {
return wtfObjCMsgSend<BOOL>(delegate, selector, self);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return result;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];

BOOL returnValue;
@try {
WebThreadCallDelegate(invocation);
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
#endif
}

static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return result;
@try {
return wtfObjCMsgSend<BOOL>(delegate, selector, self, object);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return result;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object atIndex:3];

BOOL returnValue;
@try {
WebThreadCallDelegate(invocation);
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
#endif
}

static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object, BOOL boolean)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return result;
@try {
return wtfObjCMsgSend<BOOL>(delegate, selector, self, object, boolean);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return result;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object atIndex:3];
[invocation setArgument:&boolean atIndex:4];

BOOL returnValue;
@try {
WebThreadCallDelegate(invocation);
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
#endif
}

static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object, BOOL boolean, id object2)
{
if (!delegate || ![delegate respondsToSelector:selector])
return result;
@try {
return wtfObjCMsgSend<BOOL>(delegate, selector, self, object, boolean, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
}

static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object1, id object2)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate || ![delegate respondsToSelector:selector])
return result;
@try {
return wtfObjCMsgSend<BOOL>(delegate, selector, self, object1, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return result;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object1 atIndex:3];
[invocation setArgument:&object2 atIndex:4];

BOOL returnValue;
@try {
WebThreadCallDelegate(invocation);
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
#endif
}

#if PLATFORM(IOS_FAMILY)
static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object1, id object2, BOOL boolean)
{
if (!delegate || ![delegate respondsToSelector:selector])
return result;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object1 atIndex:3];
[invocation setArgument:&object2 atIndex:4];
[invocation setArgument:&boolean atIndex:5];

BOOL returnValue;
@try {
WebThreadCallDelegate(invocation);
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
}
#endif

static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, NSUInteger integer)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, integer);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate || ![delegate respondsToSelector:selector])
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&integer atIndex:3];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object atIndex:3];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

#if PLATFORM(IOS_FAMILY)
static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2)
{
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
}

static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
{
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, object3);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
}

static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3, id object4)
{
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, object3, object4);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
}

static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, NSUInteger integer)
{
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, integer);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
}

#endif // PLATFORM(IOS_FAMILY)

static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object1 atIndex:3];
[invocation setArgument:&object2 atIndex:4];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

#if PLATFORM(IOS_FAMILY)
static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object, double double1)
{
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object atIndex:3];
[invocation setArgument:&double1 atIndex:4];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
}
#endif

static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, object3);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object1 atIndex:3];
[invocation setArgument:&object2 atIndex:4];
[invocation setArgument:&object3 atIndex:5];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3, id object4)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, object3, object4);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object1 atIndex:3];
[invocation setArgument:&object2 atIndex:4];
[invocation setArgument:&object3 atIndex:5];
[invocation setArgument:&object4 atIndex:6];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, integer, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object1 atIndex:3];
[invocation setArgument:&integer atIndex:4];
[invocation setArgument:&object2 atIndex:5];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

#if !PLATFORM(IOS_FAMILY)
static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, int integer2, id object2)
#else
static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, int integer2, id object2)
#endif
{
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, integer1, integer2, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
}

static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, BOOL boolean, NSInteger integer1, int integer2, id object2)
{
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, boolean, integer1, integer2, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
}

static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, NSInteger integer, id object3)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, integer, object3);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object1 atIndex:3];
[invocation setArgument:&object2 atIndex:4];
[invocation setArgument:&integer atIndex:5];
[invocation setArgument:&object3 atIndex:6];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

#if PLATFORM(IOS_FAMILY)
static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2)
{
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, integer, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
}
static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, NSInteger integer, id object3)
{
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, integer, object3);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
}
#endif

#if !PLATFORM(IOS_FAMILY)
static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3)
#else
static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3)
#endif
{
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, integer1, object2, integer2, object3);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
}

#if !PLATFORM(IOS_FAMILY)
static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4)
#else
static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4)
#endif
{
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, integer, object2, object3, object4);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
}

static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSTimeInterval interval, id object2, id object3)
{
#if !PLATFORM(IOS_FAMILY)
if (!delegate)
return nil;
@try {
return wtfCallIMP<id>(implementation, delegate, selector, self, object1, interval, object2, object3);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&self atIndex:2];
[invocation setArgument:&object1 atIndex:3];
[invocation setArgument:&interval atIndex:4];
[invocation setArgument:&object2 atIndex:5];
[invocation setArgument:&object3 atIndex:6];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

id CallUIDelegate(WebView *self, SEL selector)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(self, self->_private->UIDelegate, selector);
#else
return CallDelegate(self, [self _UIDelegateForSelector:selector], selector);
#endif
}

id CallUIDelegate(WebView *self, SEL selector, id object)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(self, self->_private->UIDelegate, selector, object);
#else
return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, object);
#endif
}

id CallUIDelegate(WebView *self, SEL selector, id object, BOOL boolean)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(self, self->_private->UIDelegate, selector, object, boolean);
#else
return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, object, boolean);
#endif
}

id CallUIDelegate(WebView *self, SEL selector, NSRect rect)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(self, self->_private->UIDelegate, selector, rect);
#else
return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, rect);
#endif
}

id CallUIDelegate(WebView *self, SEL selector, id object1, id object2)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2);
#else
return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, object1, object2);
#endif
}

id CallUIDelegate(WebView *self, SEL selector, id object1, id object2, id object3)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2, object3);
#else
return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, object1, object2, object3);
#endif
}

id CallUIDelegate(WebView *self, SEL selector, id object, NSUInteger integer)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(self, self->_private->UIDelegate, selector, object, integer);
#else
return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, object, integer);
#endif
}

float CallUIDelegateReturningFloat(WebView *self, SEL selector)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegateReturningFloat(self, self->_private->UIDelegate, selector);
#else
return CallDelegateReturningFloat(self, [self _UIDelegateForSelector:selector], selector);
#endif
}

BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector);
#else
return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector);
#endif
}

BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object);
#else
return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector, object);
#endif
}

BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean);
#else
return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector, object, boolean);
#endif
}

BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean, id object2)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean, object2);
#else
return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector, object, boolean, object2);
#endif
}

BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, id object2)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object1, object2);
#else
return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector, object1, object2);
#endif
}

#if PLATFORM(IOS_FAMILY)
BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, id object2, BOOL boolean)
{
return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector, object1, object2, boolean);
}
#endif

id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector);
#else
return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector);
#endif
}

id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, NSUInteger integer)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, integer);
#else
return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, integer);
#endif
}

id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object);
#else
return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object);
#endif
}

id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2);
#else
return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object1, object2);
#endif
}

id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3);
#else
return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object1, object2, object3);
#endif
}

id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3, object4);
#else
return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object1, object2, object3, object4);
#endif
}

id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSTimeInterval interval, id object2, id object3)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, interval, object2, object3);
#else
return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object1, interval, object2, object3);
#endif
}

#if PLATFORM(IOS_FAMILY)
id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object, double double1)
{
return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object, double1);
}
#endif

BOOL CallFrameLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector)
{
@try {
#if !PLATFORM(IOS_FAMILY)
return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)(self->_private->frameLoadDelegate, selector, self);
#else
return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)([self _frameLoadDelegateForwarder], selector, self);
#endif
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
}

id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2);
#else
return CallDelegate(implementation, self, [self _resourceLoadDelegateForwarder], selector, object1, object2);
#endif
}

id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3);
#else
return CallDelegate(implementation, self, [self _resourceLoadDelegateForwarder], selector, object1, object2, object3);
#endif
}

id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3, object4);
#else
return CallDelegate(implementation, self, [self _resourceLoadDelegateForwarder], selector, object1, object2, object3, object4);
#endif
}

id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, integer, object2);
#else
return CallDelegate(implementation, self, [self _resourceLoadDelegateForwarder], selector, object1, integer, object2);
#endif
}

id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, integer, object3);
#else
return CallDelegate(implementation, self, [self _resourceLoadDelegateForwarder], selector, object1, object2, integer, object3);
#endif
}

#if PLATFORM(IOS_FAMILY)
id CallResourceLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, id object1, id object2)
{
return CallDelegateInWebThread(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2);
}

id CallResourceLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
{
return CallDelegateInWebThread(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3);
}

id CallResourceLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
{
return CallDelegateInWebThread(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3, object4);
}

id CallResourceLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2)
{
return CallDelegateInWebThread(implementation, self, self->_private->resourceProgressDelegate, selector, object1, integer, object2);
}

id CallResourceLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3)
{
return CallDelegateInWebThread(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, integer, object3);
}

id CallFrameLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, NSUInteger integer)
{
return CallDelegateInWebThread(implementation, self, self->_private->frameLoadDelegate, selector, integer);
}
#endif // PLATFORM(IOS_FAMILY)

BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1)
{
@try {
return wtfObjCMsgSend<BOOL>(self->_private->resourceProgressDelegate, selector, self, object1);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
}

BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1, id object2)
{
@try {
return wtfObjCMsgSend<BOOL>(self->_private->resourceProgressDelegate, selector, self, object1, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
}

BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
{
@try {
return wtfObjCMsgSend<BOOL>(self->_private->resourceProgressDelegate, selector, self, object1, object2, object3);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
}

id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, object2, integer, object3);
#else
return CallDelegateInWebThread(implementation, self, self->_private->scriptDebugDelegate, selector, object1, object2, integer, object3);
#endif
}

id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, object2, integer2, object3);
#else
return CallDelegateInWebThread(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, object2, integer2, object3);
#endif
}

id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer, object2, object3, object4);
#else
return CallDelegateInWebThread(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer, object2, object3, object4);
#endif
}

id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, int integer2, id object2)
{
#if !PLATFORM(IOS_FAMILY)
return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, integer2, object2);
#else
return CallDelegateInWebThread(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, integer2, object2);
#endif
}

id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, BOOL boolean, NSInteger integer1, int integer2, id object2)
{
return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, boolean, integer1, integer2, object2);
}

id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector)
{
return CallDelegate(implementation, self, self->_private->historyDelegate, selector);
}

id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
{
return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2);
}

id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
{
return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2, object3);
}

// The form delegate needs to have it's own implementation, because the first argument is never the WebView

id CallFormDelegate(WebView *self, SEL selector, id object1, id object2)
{
#if !PLATFORM(IOS_FAMILY)
id delegate = self->_private->formDelegate;
if (!delegate || ![delegate respondsToSelector:selector])
return nil;
@try {
return wtfObjCMsgSend<id>(delegate, selector, object1, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
id delegate = [self _formDelegateForSelector:selector];
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&object1 atIndex:2];
[invocation setArgument:&object2 atIndex:3];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

id CallFormDelegate(WebView *self, SEL selector, id object1, id object2, id object3)
{
#if !PLATFORM(IOS_FAMILY)
id delegate = self->_private->formDelegate;
if (!delegate || ![delegate respondsToSelector:selector])
return nil;
@try {
return wtfObjCMsgSend<id>(delegate, selector, object1, object2, object3);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
id delegate = [self _formDelegateForSelector:selector];
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&object1 atIndex:2];
[invocation setArgument:&object2 atIndex:3];
[invocation setArgument:&object3 atIndex:4];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

id CallFormDelegate(WebView *self, SEL selector, id object1, id object2, id object3, id object4, id object5)
{
#if !PLATFORM(IOS_FAMILY)
id delegate = self->_private->formDelegate;
if (!delegate || ![delegate respondsToSelector:selector])
return nil;
@try {
return wtfObjCMsgSend<id>(delegate, selector, object1, object2, object3, object4, object5);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#else
id delegate = [self _formDelegateForSelector:selector];
if (!delegate)
return nil;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&object1 atIndex:2];
[invocation setArgument:&object2 atIndex:3];
[invocation setArgument:&object3 atIndex:4];
[invocation setArgument:&object4 atIndex:5];
[invocation setArgument:&object5 atIndex:6];

id returnValue;
@try {
WebThreadCallDelegate(invocation);
if ([[invocation methodSignature] methodReturnLength] == 0) {
return nil;
}
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return nil;
#endif
}

BOOL CallFormDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, SEL selectorArg, id object2)
{
#if !PLATFORM(IOS_FAMILY)
id delegate = self->_private->formDelegate;
if (!delegate || ![delegate respondsToSelector:selector])
return result;
@try {
return wtfObjCMsgSend<BOOL>(delegate, selector, object1, selectorArg, object2);
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
#else
id delegate = [self _formDelegateForSelector:selector];
if (!delegate)
return result;

NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
[invocation setArgument:&object1 atIndex:2];
[invocation setArgument:&selectorArg atIndex:3];
[invocation setArgument:&object2 atIndex:4];

BOOL returnValue;
@try {
WebThreadCallDelegate(invocation);
[invocation getReturnValue:&returnValue];
return returnValue;
} @catch(id exception) {
ReportDiscardedDelegateException(selector, exception);
}
return result;
#endif
}

@end