1/*
2 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2006 David Smith (catfish.man@gmail.com)
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1.  Redistributions of source code must retain the above copyright
10 *     notice, this list of conditions and the following disclaimer.
11 * 2.  Redistributions in binary form must reproduce the above copyright
12 *     notice, this list of conditions and the following disclaimer in the
13 *     documentation and/or other materials provided with the distribution.
14 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15 *     its contributors may be used to endorse or promote products derived
16 *     from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#import "WebDelegateImplementationCaching.h"
31
32#import "WebKitLogging.h"
33#import "WebView.h"
34#import "WebViewData.h"
35#import <wtf/ObjcRuntimeExtras.h>
36
37#if PLATFORM(IOS)
38#import "WebViewInternal.h"
39#import <WebCore/WebCoreThreadMessage.h>
40#endif
41
42@implementation WebView (WebDelegateImplementationCaching)
43
44WebResourceDelegateImplementationCache* WebViewGetResourceLoadDelegateImplementations(WebView *webView)
45{
46    static WebResourceDelegateImplementationCache empty;
47    if (!webView)
48        return &empty;
49    return &webView->_private->resourceLoadDelegateImplementations;
50}
51
52WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementations(WebView *webView)
53{
54    static WebFrameLoadDelegateImplementationCache empty;
55    if (!webView)
56        return &empty;
57    return &webView->_private->frameLoadDelegateImplementations;
58}
59
60WebScriptDebugDelegateImplementationCache* WebViewGetScriptDebugDelegateImplementations(WebView *webView)
61{
62    static WebScriptDebugDelegateImplementationCache empty;
63    if (!webView)
64        return &empty;
65    return &webView->_private->scriptDebugDelegateImplementations;
66}
67
68WebHistoryDelegateImplementationCache* WebViewGetHistoryDelegateImplementations(WebView *webView)
69{
70    static WebHistoryDelegateImplementationCache empty;
71    if (!webView)
72        return &empty;
73    return &webView->_private->historyDelegateImplementations;
74}
75
76// We use these functions to call the delegates and block exceptions. These functions are
77// declared inside a WebView category to get direct access to the delegate data memebers,
78// preventing more ObjC message dispatch and compensating for the expense of the @try/@catch.
79
80typedef float (*ObjCMsgSendFPRet)(id, SEL, ...);
81#if !PLATFORM(IOS)
82#if defined(__i386__)
83static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend_fpret);
84#else
85static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend);
86#endif
87#endif
88
89static inline id CallDelegate(WebView *self, id delegate, SEL selector)
90{
91#if !PLATFORM(IOS)
92    if (!delegate || ![delegate respondsToSelector:selector])
93        return nil;
94    @try {
95        return wtfObjcMsgSend<id>(delegate, selector, self);
96    } @catch(id exception) {
97        ReportDiscardedDelegateException(selector, exception);
98    }
99    return nil;
100#else
101    if (!delegate || ![delegate respondsToSelector:selector])
102        return nil;
103
104    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
105    [invocation setArgument:&self atIndex:2];
106
107    id returnValue;
108    @try {
109        WebThreadCallDelegate(invocation);
110        if ([[invocation methodSignature] methodReturnLength] == 0) {
111            return nil;
112        }
113        [invocation getReturnValue:&returnValue];
114        return returnValue;
115    } @catch(id exception) {
116        ReportDiscardedDelegateException(selector, exception);
117    }
118    return nil;
119#endif
120}
121
122static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object)
123{
124#if !PLATFORM(IOS)
125    if (!delegate || ![delegate respondsToSelector:selector])
126        return nil;
127    @try {
128        return wtfObjcMsgSend<id>(delegate, selector, self, object);
129    } @catch(id exception) {
130        ReportDiscardedDelegateException(selector, exception);
131    }
132    return nil;
133#else
134    if (!delegate || ![delegate respondsToSelector:selector])
135        return nil;
136
137    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
138    [invocation setArgument:&self atIndex:2];
139    [invocation setArgument:&object atIndex:3];
140
141    id returnValue;
142    @try {
143        WebThreadCallDelegate(invocation);
144        if ([[invocation methodSignature] methodReturnLength] == 0) {
145            return nil;
146        }
147        [invocation getReturnValue:&returnValue];
148        return returnValue;
149    } @catch(id exception) {
150        ReportDiscardedDelegateException(selector, exception);
151    }
152    return nil;
153#endif
154}
155
156static inline id CallDelegate(WebView *self, id delegate, SEL selector, NSRect rect)
157{
158#if !PLATFORM(IOS)
159    if (!delegate || ![delegate respondsToSelector:selector])
160        return nil;
161    @try {
162        return wtfObjcMsgSend<id>(delegate, selector, self, rect);
163    } @catch(id exception) {
164        ReportDiscardedDelegateException(selector, exception);
165    }
166    return nil;
167#else
168    if (!delegate || ![delegate respondsToSelector:selector])
169        return nil;
170
171    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
172    [invocation setArgument:&self atIndex:2];
173    [invocation setArgument:&rect atIndex:3];
174
175    id returnValue;
176    @try {
177        WebThreadCallDelegate(invocation);
178        if ([[invocation methodSignature] methodReturnLength] == 0) {
179            return nil;
180        }
181        [invocation getReturnValue:&returnValue];
182        return returnValue;
183    } @catch(id exception) {
184        ReportDiscardedDelegateException(selector, exception);
185    }
186    return nil;
187#endif
188}
189
190static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2)
191{
192#if !PLATFORM(IOS)
193    if (!delegate || ![delegate respondsToSelector:selector])
194        return nil;
195    @try {
196        return wtfObjcMsgSend<id>(delegate, selector, self, object1, object2);
197    } @catch(id exception) {
198        ReportDiscardedDelegateException(selector, exception);
199    }
200    return nil;
201#else
202    if (!delegate || ![delegate respondsToSelector:selector])
203        return nil;
204
205    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
206    [invocation setArgument:&self atIndex:2];
207    [invocation setArgument:&object1 atIndex:3];
208    [invocation setArgument:&object2 atIndex:4];
209
210    id returnValue;
211    @try {
212        WebThreadCallDelegate(invocation);
213        if ([[invocation methodSignature] methodReturnLength] == 0) {
214            return nil;
215        }
216        [invocation getReturnValue:&returnValue];
217        return returnValue;
218    } @catch(id exception) {
219        ReportDiscardedDelegateException(selector, exception);
220    }
221    return nil;
222#endif
223}
224
225static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, BOOL boolean)
226{
227#if !PLATFORM(IOS)
228    if (!delegate || ![delegate respondsToSelector:selector])
229        return nil;
230    @try {
231        return wtfObjcMsgSend<id>(delegate, selector, self, object, boolean);
232    } @catch(id exception) {
233        ReportDiscardedDelegateException(selector, exception);
234    }
235    return nil;
236#else
237    if (!delegate || ![delegate respondsToSelector:selector])
238        return nil;
239
240    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
241    [invocation setArgument:&self atIndex:2];
242    [invocation setArgument:&object atIndex:3];
243    [invocation setArgument:&boolean atIndex:4];
244
245    id returnValue;
246    @try {
247        WebThreadCallDelegate(invocation);
248        if ([[invocation methodSignature] methodReturnLength] == 0) {
249            return nil;
250        }
251        [invocation getReturnValue:&returnValue];
252        return returnValue;
253    } @catch(id exception) {
254        ReportDiscardedDelegateException(selector, exception);
255    }
256    return nil;
257#endif
258}
259
260static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
261{
262#if !PLATFORM(IOS)
263    if (!delegate || ![delegate respondsToSelector:selector])
264        return nil;
265    @try {
266        return wtfObjcMsgSend<id>(delegate, selector, self, object1, object2, object3);
267    } @catch(id exception) {
268        ReportDiscardedDelegateException(selector, exception);
269    }
270    return nil;
271#else
272    if (!delegate || ![delegate respondsToSelector:selector])
273        return nil;
274
275    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
276    [invocation setArgument:&self atIndex:2];
277    [invocation setArgument:&object1 atIndex:3];
278    [invocation setArgument:&object2 atIndex:4];
279    [invocation setArgument:&object3 atIndex:5];
280
281    id returnValue;
282    @try {
283        WebThreadCallDelegate(invocation);
284        if ([[invocation methodSignature] methodReturnLength] == 0) {
285            return nil;
286        }
287        [invocation getReturnValue:&returnValue];
288        return returnValue;
289    } @catch(id exception) {
290        ReportDiscardedDelegateException(selector, exception);
291    }
292    return nil;
293#endif
294}
295
296static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, NSUInteger integer)
297{
298#if !PLATFORM(IOS)
299    if (!delegate || ![delegate respondsToSelector:selector])
300        return nil;
301    @try {
302        return wtfObjcMsgSend<id>(delegate, selector, self, object, integer);
303    } @catch(id exception) {
304        ReportDiscardedDelegateException(selector, exception);
305    }
306    return nil;
307#else
308    if (!delegate || ![delegate respondsToSelector:selector])
309        return nil;
310
311    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
312    [invocation setArgument:&self atIndex:2];
313    [invocation setArgument:&object atIndex:3];
314    [invocation setArgument:&integer atIndex:4];
315
316    id returnValue;
317    @try {
318        WebThreadCallDelegate(invocation);
319        if ([[invocation methodSignature] methodReturnLength] == 0) {
320            return nil;
321        }
322        [invocation getReturnValue:&returnValue];
323        return returnValue;
324    } @catch(id exception) {
325        ReportDiscardedDelegateException(selector, exception);
326    }
327    return nil;
328#endif
329}
330
331static inline float CallDelegateReturningFloat(WebView *self, id delegate, SEL selector)
332{
333#if !PLATFORM(IOS)
334    if (!delegate || ![delegate respondsToSelector:selector])
335        return 0.0f;
336    @try {
337        return objc_msgSend_float_return(delegate, selector, self);
338    } @catch(id exception) {
339        ReportDiscardedDelegateException(selector, exception);
340    }
341    return 0.0f;
342#else
343    if (!delegate || ![delegate respondsToSelector:selector])
344        return 0.0f;
345
346    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
347    [invocation setArgument:&self atIndex:2];
348
349    float returnValue = 0.0f;
350    @try {
351        WebThreadCallDelegate(invocation);
352        [invocation getReturnValue:&returnValue];
353        return returnValue;
354    } @catch(id exception) {
355        ReportDiscardedDelegateException(selector, exception);
356    }
357    return 0.0f;
358#endif
359}
360
361static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector)
362{
363#if !PLATFORM(IOS)
364    if (!delegate || ![delegate respondsToSelector:selector])
365        return result;
366    @try {
367        return wtfObjcMsgSend<BOOL>(delegate, selector, self);
368    } @catch(id exception) {
369        ReportDiscardedDelegateException(selector, exception);
370    }
371    return result;
372#else
373    if (!delegate || ![delegate respondsToSelector:selector])
374        return result;
375
376    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
377    [invocation setArgument:&self atIndex:2];
378
379    BOOL returnValue;
380    @try {
381        WebThreadCallDelegate(invocation);
382        [invocation getReturnValue:&returnValue];
383        return returnValue;
384    } @catch(id exception) {
385        ReportDiscardedDelegateException(selector, exception);
386    }
387    return result;
388#endif
389}
390
391static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object)
392{
393#if !PLATFORM(IOS)
394    if (!delegate || ![delegate respondsToSelector:selector])
395        return result;
396    @try {
397        return wtfObjcMsgSend<BOOL>(delegate, selector, self, object);
398    } @catch(id exception) {
399        ReportDiscardedDelegateException(selector, exception);
400    }
401    return result;
402#else
403    if (!delegate || ![delegate respondsToSelector:selector])
404        return result;
405
406    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
407    [invocation setArgument:&self atIndex:2];
408    [invocation setArgument:&object atIndex:3];
409
410    BOOL returnValue;
411    @try {
412        WebThreadCallDelegate(invocation);
413        [invocation getReturnValue:&returnValue];
414        return returnValue;
415    } @catch(id exception) {
416        ReportDiscardedDelegateException(selector, exception);
417    }
418    return result;
419#endif
420}
421
422static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object, BOOL boolean)
423{
424#if !PLATFORM(IOS)
425    if (!delegate || ![delegate respondsToSelector:selector])
426        return result;
427    @try {
428        return wtfObjcMsgSend<BOOL>(delegate, selector, self, object, boolean);
429    } @catch(id exception) {
430        ReportDiscardedDelegateException(selector, exception);
431    }
432    return result;
433#else
434    if (!delegate || ![delegate respondsToSelector:selector])
435        return result;
436
437    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
438    [invocation setArgument:&self atIndex:2];
439    [invocation setArgument:&object atIndex:3];
440    [invocation setArgument:&boolean atIndex:4];
441
442    BOOL returnValue;
443    @try {
444        WebThreadCallDelegate(invocation);
445        [invocation getReturnValue:&returnValue];
446        return returnValue;
447    } @catch(id exception) {
448        ReportDiscardedDelegateException(selector, exception);
449    }
450    return result;
451#endif
452}
453
454static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object, BOOL boolean, id object2)
455{
456    if (!delegate || ![delegate respondsToSelector:selector])
457        return result;
458    @try {
459        return wtfObjcMsgSend<BOOL>(delegate, selector, self, object, boolean, object2);
460    } @catch(id exception) {
461        ReportDiscardedDelegateException(selector, exception);
462    }
463    return result;
464}
465
466static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object1, id object2)
467{
468#if !PLATFORM(IOS)
469    if (!delegate || ![delegate respondsToSelector:selector])
470        return result;
471    @try {
472        return wtfObjcMsgSend<BOOL>(delegate, selector, self, object1, object2);
473    } @catch(id exception) {
474        ReportDiscardedDelegateException(selector, exception);
475    }
476    return result;
477#else
478    if (!delegate || ![delegate respondsToSelector:selector])
479        return result;
480
481    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
482    [invocation setArgument:&self atIndex:2];
483    [invocation setArgument:&object1 atIndex:3];
484    [invocation setArgument:&object2 atIndex:4];
485
486    BOOL returnValue;
487    @try {
488        WebThreadCallDelegate(invocation);
489        [invocation getReturnValue:&returnValue];
490        return returnValue;
491    } @catch(id exception) {
492        ReportDiscardedDelegateException(selector, exception);
493    }
494    return result;
495#endif
496}
497
498#if PLATFORM(IOS)
499static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object1, id object2, BOOL boolean)
500{
501    if (!delegate || ![delegate respondsToSelector:selector])
502        return result;
503
504    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
505    [invocation setArgument:&self atIndex:2];
506    [invocation setArgument:&object1 atIndex:3];
507    [invocation setArgument:&object2 atIndex:4];
508    [invocation setArgument:&boolean atIndex:5];
509
510    BOOL returnValue;
511    @try {
512        WebThreadCallDelegate(invocation);
513        [invocation getReturnValue:&returnValue];
514        return returnValue;
515    } @catch(id exception) {
516        ReportDiscardedDelegateException(selector, exception);
517    }
518    return result;
519}
520#endif
521
522static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector)
523{
524#if !PLATFORM(IOS)
525    if (!delegate)
526        return nil;
527    @try {
528        return wtfCallIMP<id>(implementation, delegate, selector, self);
529    } @catch(id exception) {
530        ReportDiscardedDelegateException(selector, exception);
531    }
532    return nil;
533#else
534    if (!delegate)
535        return nil;
536
537    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
538    [invocation setArgument:&self atIndex:2];
539
540    id returnValue;
541    @try {
542        WebThreadCallDelegate(invocation);
543        if ([[invocation methodSignature] methodReturnLength] == 0) {
544            return nil;
545        }
546        [invocation getReturnValue:&returnValue];
547        return returnValue;
548    } @catch(id exception) {
549        ReportDiscardedDelegateException(selector, exception);
550    }
551    return nil;
552#endif
553}
554
555static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, NSUInteger integer)
556{
557#if !PLATFORM(IOS)
558    if (!delegate)
559        return nil;
560    @try {
561        return implementation(delegate, selector, self, integer);
562    } @catch(id exception) {
563        ReportDiscardedDelegateException(selector, exception);
564    }
565    return nil;
566#else
567    if (!delegate || ![delegate respondsToSelector:selector])
568        return nil;
569
570    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
571    [invocation setArgument:&self atIndex:2];
572    [invocation setArgument:&integer atIndex:3];
573
574    id returnValue;
575    @try {
576        WebThreadCallDelegate(invocation);
577        if ([[invocation methodSignature] methodReturnLength] == 0) {
578            return nil;
579        }
580        [invocation getReturnValue:&returnValue];
581        return returnValue;
582    } @catch(id exception) {
583        ReportDiscardedDelegateException(selector, exception);
584    }
585    return nil;
586#endif
587}
588
589static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object)
590{
591#if !PLATFORM(IOS)
592    if (!delegate)
593        return nil;
594    @try {
595        return wtfCallIMP<id>(implementation, delegate, selector, self, object);
596    } @catch(id exception) {
597        ReportDiscardedDelegateException(selector, exception);
598    }
599    return nil;
600#else
601    if (!delegate)
602        return nil;
603
604    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
605    [invocation setArgument:&self atIndex:2];
606    [invocation setArgument:&object atIndex:3];
607
608    id returnValue;
609    @try {
610        WebThreadCallDelegate(invocation);
611        if ([[invocation methodSignature] methodReturnLength] == 0) {
612            return nil;
613        }
614        [invocation getReturnValue:&returnValue];
615        return returnValue;
616    } @catch(id exception) {
617        ReportDiscardedDelegateException(selector, exception);
618    }
619    return nil;
620#endif
621}
622
623#if PLATFORM(IOS)
624static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2)
625{
626    if (!delegate)
627        return nil;
628    @try {
629        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2);
630    } @catch(id exception) {
631        ReportDiscardedDelegateException(selector, exception);
632    }
633    return nil;
634}
635
636static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
637{
638    if (!delegate)
639        return nil;
640    @try {
641        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, object3);
642    } @catch(id exception) {
643        ReportDiscardedDelegateException(selector, exception);
644    }
645    return nil;
646}
647
648static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3, id object4)
649{
650    if (!delegate)
651        return nil;
652    @try {
653        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, object3, object4);
654    } @catch(id exception) {
655        ReportDiscardedDelegateException(selector, exception);
656    }
657    return nil;
658}
659
660static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, NSUInteger integer)
661{
662    if (!delegate)
663        return nil;
664    @try {
665        return wtfCallIMP<id>(implementation, delegate, selector, self, integer);
666    } @catch(id exception) {
667        ReportDiscardedDelegateException(selector, exception);
668    }
669    return nil;
670}
671
672#endif // PLATFORM(IOS)
673
674static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2)
675{
676#if !PLATFORM(IOS)
677    if (!delegate)
678        return nil;
679    @try {
680        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2);
681    } @catch(id exception) {
682        ReportDiscardedDelegateException(selector, exception);
683    }
684    return nil;
685#else
686    if (!delegate)
687        return nil;
688
689    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
690    [invocation setArgument:&self atIndex:2];
691    [invocation setArgument:&object1 atIndex:3];
692    [invocation setArgument:&object2 atIndex:4];
693
694    id returnValue;
695    @try {
696        WebThreadCallDelegate(invocation);
697        if ([[invocation methodSignature] methodReturnLength] == 0) {
698            return nil;
699        }
700        [invocation getReturnValue:&returnValue];
701        return returnValue;
702    } @catch(id exception) {
703        ReportDiscardedDelegateException(selector, exception);
704    }
705    return nil;
706#endif
707}
708
709#if PLATFORM(IOS)
710static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object, double double1)
711{
712    if (!delegate)
713        return nil;
714
715    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
716    [invocation setArgument:&self atIndex:2];
717    [invocation setArgument:&object atIndex:3];
718    [invocation setArgument:&double1 atIndex:4];
719
720    id returnValue;
721    @try {
722        WebThreadCallDelegate(invocation);
723        if ([[invocation methodSignature] methodReturnLength] == 0) {
724            return nil;
725        }
726        [invocation getReturnValue:&returnValue];
727        return returnValue;
728    } @catch(id exception) {
729        ReportDiscardedDelegateException(selector, exception);
730    }
731    return nil;
732}
733#endif
734
735static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
736{
737#if !PLATFORM(IOS)
738    if (!delegate)
739        return nil;
740    @try {
741        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, object3);
742    } @catch(id exception) {
743        ReportDiscardedDelegateException(selector, exception);
744    }
745    return nil;
746#else
747    if (!delegate)
748        return nil;
749
750    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
751    [invocation setArgument:&self atIndex:2];
752    [invocation setArgument:&object1 atIndex:3];
753    [invocation setArgument:&object2 atIndex:4];
754    [invocation setArgument:&object3 atIndex:5];
755
756    id returnValue;
757    @try {
758        WebThreadCallDelegate(invocation);
759        if ([[invocation methodSignature] methodReturnLength] == 0) {
760            return nil;
761        }
762        [invocation getReturnValue:&returnValue];
763        return returnValue;
764    } @catch(id exception) {
765        ReportDiscardedDelegateException(selector, exception);
766    }
767    return nil;
768#endif
769}
770
771static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3, id object4)
772{
773#if !PLATFORM(IOS)
774    if (!delegate)
775        return nil;
776    @try {
777        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, object3, object4);
778    } @catch(id exception) {
779        ReportDiscardedDelegateException(selector, exception);
780    }
781    return nil;
782#else
783    if (!delegate)
784        return nil;
785
786    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
787    [invocation setArgument:&self atIndex:2];
788    [invocation setArgument:&object1 atIndex:3];
789    [invocation setArgument:&object2 atIndex:4];
790    [invocation setArgument:&object3 atIndex:5];
791    [invocation setArgument:&object4 atIndex:6];
792
793    id returnValue;
794    @try {
795        WebThreadCallDelegate(invocation);
796        if ([[invocation methodSignature] methodReturnLength] == 0) {
797            return nil;
798        }
799        [invocation getReturnValue:&returnValue];
800        return returnValue;
801    } @catch(id exception) {
802        ReportDiscardedDelegateException(selector, exception);
803    }
804    return nil;
805#endif
806}
807
808static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2)
809{
810#if !PLATFORM(IOS)
811    if (!delegate)
812        return nil;
813    @try {
814        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, integer, object2);
815    } @catch(id exception) {
816        ReportDiscardedDelegateException(selector, exception);
817    }
818    return nil;
819#else
820    if (!delegate)
821        return nil;
822
823    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
824    [invocation setArgument:&self atIndex:2];
825    [invocation setArgument:&object1 atIndex:3];
826    [invocation setArgument:&integer atIndex:4];
827    [invocation setArgument:&object2 atIndex:5];
828
829    id returnValue;
830    @try {
831        WebThreadCallDelegate(invocation);
832        if ([[invocation methodSignature] methodReturnLength] == 0) {
833            return nil;
834        }
835        [invocation getReturnValue:&returnValue];
836        return returnValue;
837    } @catch(id exception) {
838        ReportDiscardedDelegateException(selector, exception);
839    }
840    return nil;
841#endif
842}
843
844#if !PLATFORM(IOS)
845static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, int integer2, id object2)
846#else
847static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, int integer2, id object2)
848#endif
849{
850    if (!delegate)
851        return nil;
852    @try {
853        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, integer1, integer2, object2);
854    } @catch(id exception) {
855        ReportDiscardedDelegateException(selector, exception);
856    }
857    return nil;
858}
859
860static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, BOOL boolean, NSInteger integer1, int integer2, id object2)
861{
862    if (!delegate)
863        return nil;
864    @try {
865        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, boolean, integer1, integer2, object2);
866    } @catch(id exception) {
867        ReportDiscardedDelegateException(selector, exception);
868    }
869    return nil;
870}
871
872static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, NSInteger integer, id object3)
873{
874#if !PLATFORM(IOS)
875    if (!delegate)
876        return nil;
877    @try {
878        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, integer, object3);
879    } @catch(id exception) {
880        ReportDiscardedDelegateException(selector, exception);
881    }
882    return nil;
883#else
884    if (!delegate)
885        return nil;
886
887    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
888    [invocation setArgument:&self atIndex:2];
889    [invocation setArgument:&object1 atIndex:3];
890    [invocation setArgument:&object2 atIndex:4];
891    [invocation setArgument:&integer atIndex:5];
892    [invocation setArgument:&object3 atIndex:6];
893
894    id returnValue;
895    @try {
896        WebThreadCallDelegate(invocation);
897        if ([[invocation methodSignature] methodReturnLength] == 0) {
898            return nil;
899        }
900        [invocation getReturnValue:&returnValue];
901        return returnValue;
902    } @catch(id exception) {
903        ReportDiscardedDelegateException(selector, exception);
904    }
905    return nil;
906#endif
907}
908
909#if PLATFORM(IOS)
910static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2)
911{
912    if (!delegate)
913        return nil;
914    @try {
915        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, integer, object2);
916    } @catch(id exception) {
917        ReportDiscardedDelegateException(selector, exception);
918    }
919    return nil;
920}
921static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, NSInteger integer, id object3)
922{
923    if (!delegate)
924        return nil;
925    @try {
926        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, object2, integer, object3);
927    } @catch(id exception) {
928        ReportDiscardedDelegateException(selector, exception);
929    }
930    return nil;
931}
932#endif
933
934#if !PLATFORM(IOS)
935static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3)
936#else
937static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3)
938#endif
939{
940    if (!delegate)
941        return nil;
942    @try {
943        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, integer1, object2, integer2, object3);
944    } @catch(id exception) {
945        ReportDiscardedDelegateException(selector, exception);
946    }
947    return nil;
948}
949
950#if !PLATFORM(IOS)
951static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4)
952#else
953static inline id CallDelegateInWebThread(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4)
954#endif
955{
956    if (!delegate)
957        return nil;
958    @try {
959        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, integer, object2, object3, object4);
960    } @catch(id exception) {
961        ReportDiscardedDelegateException(selector, exception);
962    }
963    return nil;
964}
965
966static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSTimeInterval interval, id object2, id object3)
967{
968#if !PLATFORM(IOS)
969    if (!delegate)
970        return nil;
971    @try {
972        return wtfCallIMP<id>(implementation, delegate, selector, self, object1, interval, object2, object3);
973    } @catch(id exception) {
974        ReportDiscardedDelegateException(selector, exception);
975    }
976    return nil;
977#else
978    if (!delegate)
979        return nil;
980
981    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
982    [invocation setArgument:&self atIndex:2];
983    [invocation setArgument:&object1 atIndex:3];
984    [invocation setArgument:&interval atIndex:4];
985    [invocation setArgument:&object2 atIndex:5];
986    [invocation setArgument:&object3 atIndex:6];
987
988    id returnValue;
989    @try {
990        WebThreadCallDelegate(invocation);
991        if ([[invocation methodSignature] methodReturnLength] == 0) {
992            return nil;
993        }
994        [invocation getReturnValue:&returnValue];
995        return returnValue;
996    } @catch(id exception) {
997        ReportDiscardedDelegateException(selector, exception);
998    }
999    return nil;
1000#endif
1001}
1002
1003id CallUIDelegate(WebView *self, SEL selector)
1004{
1005#if !PLATFORM(IOS)
1006    return CallDelegate(self, self->_private->UIDelegate, selector);
1007#else
1008    return CallDelegate(self, [self _UIDelegateForSelector:selector], selector);
1009#endif
1010}
1011
1012id CallUIDelegate(WebView *self, SEL selector, id object)
1013{
1014#if !PLATFORM(IOS)
1015    return CallDelegate(self, self->_private->UIDelegate, selector, object);
1016#else
1017    return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, object);
1018#endif
1019}
1020
1021id CallUIDelegate(WebView *self, SEL selector, id object, BOOL boolean)
1022{
1023#if !PLATFORM(IOS)
1024    return CallDelegate(self, self->_private->UIDelegate, selector, object, boolean);
1025#else
1026    return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, object, boolean);
1027#endif
1028}
1029
1030id CallUIDelegate(WebView *self, SEL selector, NSRect rect)
1031{
1032#if !PLATFORM(IOS)
1033    return CallDelegate(self, self->_private->UIDelegate, selector, rect);
1034#else
1035    return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, rect);
1036#endif
1037}
1038
1039id CallUIDelegate(WebView *self, SEL selector, id object1, id object2)
1040{
1041#if !PLATFORM(IOS)
1042    return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2);
1043#else
1044    return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, object1, object2);
1045#endif
1046}
1047
1048id CallUIDelegate(WebView *self, SEL selector, id object1, id object2, id object3)
1049{
1050#if !PLATFORM(IOS)
1051    return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2, object3);
1052#else
1053    return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, object1, object2, object3);
1054#endif
1055}
1056
1057id CallUIDelegate(WebView *self, SEL selector, id object, NSUInteger integer)
1058{
1059#if !PLATFORM(IOS)
1060    return CallDelegate(self, self->_private->UIDelegate, selector, object, integer);
1061#else
1062    return CallDelegate(self, [self _UIDelegateForSelector:selector], selector, object, integer);
1063#endif
1064}
1065
1066float CallUIDelegateReturningFloat(WebView *self, SEL selector)
1067{
1068#if !PLATFORM(IOS)
1069    return CallDelegateReturningFloat(self, self->_private->UIDelegate, selector);
1070#else
1071    return CallDelegateReturningFloat(self, [self _UIDelegateForSelector:selector], selector);
1072#endif
1073}
1074
1075BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector)
1076{
1077#if !PLATFORM(IOS)
1078    return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector);
1079#else
1080    return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector);
1081#endif
1082}
1083
1084BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object)
1085{
1086#if !PLATFORM(IOS)
1087    return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object);
1088#else
1089    return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector, object);
1090#endif
1091}
1092
1093BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean)
1094{
1095#if !PLATFORM(IOS)
1096    return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean);
1097#else
1098    return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector, object, boolean);
1099#endif
1100}
1101
1102BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean, id object2)
1103{
1104#if !PLATFORM(IOS)
1105    return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean, object2);
1106#else
1107    return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector, object, boolean, object2);
1108#endif
1109}
1110
1111BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, id object2)
1112{
1113#if !PLATFORM(IOS)
1114    return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object1, object2);
1115#else
1116    return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector, object1, object2);
1117#endif
1118}
1119
1120#if PLATFORM(IOS)
1121BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, id object2, BOOL boolean)
1122{
1123    return CallDelegateReturningBoolean(result, self, [self _UIDelegateForSelector:selector], selector, object1, object2, boolean);
1124}
1125#endif
1126
1127id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector)
1128{
1129#if !PLATFORM(IOS)
1130    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector);
1131#else
1132    return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector);
1133#endif
1134}
1135
1136id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, NSUInteger integer)
1137{
1138#if !PLATFORM(IOS)
1139    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, integer);
1140#else
1141    return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, integer);
1142#endif
1143}
1144
1145id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object)
1146{
1147#if !PLATFORM(IOS)
1148    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object);
1149#else
1150    return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object);
1151#endif
1152}
1153
1154id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
1155{
1156#if !PLATFORM(IOS)
1157    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2);
1158#else
1159    return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object1, object2);
1160#endif
1161}
1162
1163id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
1164{
1165#if !PLATFORM(IOS)
1166    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3);
1167#else
1168    return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object1, object2, object3);
1169#endif
1170}
1171
1172id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
1173{
1174#if !PLATFORM(IOS)
1175    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3, object4);
1176#else
1177    return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object1, object2, object3, object4);
1178#endif
1179}
1180
1181id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSTimeInterval interval, id object2, id object3)
1182{
1183#if !PLATFORM(IOS)
1184    return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, interval, object2, object3);
1185#else
1186    return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object1, interval, object2, object3);
1187#endif
1188}
1189
1190#if PLATFORM(IOS)
1191id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object, double double1)
1192{
1193    return CallDelegate(implementation, self, [self _frameLoadDelegateForwarder], selector, object, double1);
1194}
1195#endif
1196
1197BOOL CallFrameLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector)
1198{
1199    @try {
1200#if !PLATFORM(IOS)
1201        return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)(self->_private->frameLoadDelegate, selector, self);
1202#else
1203        return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)([self _frameLoadDelegateForwarder], selector, self);
1204#endif
1205    } @catch(id exception) {
1206        ReportDiscardedDelegateException(selector, exception);
1207    }
1208    return result;
1209}
1210
1211id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
1212{
1213#if !PLATFORM(IOS)
1214    return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2);
1215#else
1216    return CallDelegate(implementation, self, [self _resourceLoadDelegateForwarder], selector, object1, object2);
1217#endif
1218}
1219
1220id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
1221{
1222#if !PLATFORM(IOS)
1223    return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3);
1224#else
1225    return CallDelegate(implementation, self, [self _resourceLoadDelegateForwarder], selector, object1, object2, object3);
1226#endif
1227}
1228
1229id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
1230{
1231#if !PLATFORM(IOS)
1232    return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3, object4);
1233#else
1234    return CallDelegate(implementation, self, [self _resourceLoadDelegateForwarder], selector, object1, object2, object3, object4);
1235#endif
1236}
1237
1238id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2)
1239{
1240#if !PLATFORM(IOS)
1241    return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, integer, object2);
1242#else
1243    return CallDelegate(implementation, self, [self _resourceLoadDelegateForwarder], selector, object1, integer, object2);
1244#endif
1245}
1246
1247id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3)
1248{
1249#if !PLATFORM(IOS)
1250    return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, integer, object3);
1251#else
1252    return CallDelegate(implementation, self, [self _resourceLoadDelegateForwarder], selector, object1, object2, integer, object3);
1253#endif
1254}
1255
1256#if PLATFORM(IOS)
1257id CallResourceLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, id object1, id object2)
1258{
1259    return CallDelegateInWebThread(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2);
1260}
1261
1262id CallResourceLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
1263{
1264    return CallDelegateInWebThread(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3);
1265}
1266
1267id CallResourceLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
1268{
1269    return CallDelegateInWebThread(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3, object4);
1270}
1271
1272id CallResourceLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2)
1273{
1274    return CallDelegateInWebThread(implementation, self, self->_private->resourceProgressDelegate, selector, object1, integer, object2);
1275}
1276
1277id CallResourceLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3)
1278{
1279    return CallDelegateInWebThread(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, integer, object3);
1280}
1281
1282id CallFrameLoadDelegateInWebThread(IMP implementation, WebView *self, SEL selector, NSUInteger integer)
1283{
1284    return CallDelegateInWebThread(implementation, self, self->_private->frameLoadDelegate, selector, integer);
1285}
1286#endif // PLATFORM(IOS)
1287
1288BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1)
1289{
1290    @try {
1291        return wtfObjcMsgSend<BOOL>(self->_private->resourceProgressDelegate, selector, self, object1);
1292    } @catch(id exception) {
1293        ReportDiscardedDelegateException(selector, exception);
1294    }
1295    return result;
1296}
1297
1298BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1, id object2)
1299{
1300    @try {
1301        return wtfObjcMsgSend<BOOL>(self->_private->resourceProgressDelegate, selector, self, object1, object2);
1302    } @catch(id exception) {
1303        ReportDiscardedDelegateException(selector, exception);
1304    }
1305    return result;
1306}
1307
1308BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
1309{
1310    @try {
1311        return wtfObjcMsgSend<BOOL>(self->_private->resourceProgressDelegate, selector, self, object1, object2, object3);
1312    } @catch(id exception) {
1313        ReportDiscardedDelegateException(selector, exception);
1314    }
1315    return result;
1316}
1317
1318id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3)
1319{
1320#if !PLATFORM(IOS)
1321    return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, object2, integer, object3);
1322#else
1323    return CallDelegateInWebThread(implementation, self, self->_private->scriptDebugDelegate, selector, object1, object2, integer, object3);
1324#endif
1325}
1326
1327id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3)
1328{
1329#if !PLATFORM(IOS)
1330    return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, object2, integer2, object3);
1331#else
1332    return CallDelegateInWebThread(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, object2, integer2, object3);
1333#endif
1334}
1335
1336id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4)
1337{
1338#if !PLATFORM(IOS)
1339    return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer, object2, object3, object4);
1340#else
1341    return CallDelegateInWebThread(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer, object2, object3, object4);
1342#endif
1343}
1344
1345id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, int integer2, id object2)
1346{
1347#if !PLATFORM(IOS)
1348    return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, integer2, object2);
1349#else
1350    return CallDelegateInWebThread(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, integer2, object2);
1351#endif
1352}
1353
1354id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, BOOL boolean, NSInteger integer1, int integer2, id object2)
1355{
1356    return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, boolean, integer1, integer2, object2);
1357}
1358
1359id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector)
1360{
1361    return CallDelegate(implementation, self, self->_private->historyDelegate, selector);
1362}
1363
1364id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
1365{
1366    return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2);
1367}
1368
1369id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
1370{
1371    return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2, object3);
1372}
1373
1374// The form delegate needs to have it's own implementation, because the first argument is never the WebView
1375
1376id CallFormDelegate(WebView *self, SEL selector, id object1, id object2)
1377{
1378#if !PLATFORM(IOS)
1379    id delegate = self->_private->formDelegate;
1380    if (!delegate || ![delegate respondsToSelector:selector])
1381        return nil;
1382    @try {
1383        return wtfObjcMsgSend<id>(delegate, selector, object1, object2);
1384    } @catch(id exception) {
1385        ReportDiscardedDelegateException(selector, exception);
1386    }
1387    return nil;
1388#else
1389    id delegate = [self _formDelegateForSelector:selector];
1390    if (!delegate)
1391        return nil;
1392
1393    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
1394    [invocation setArgument:&object1 atIndex:2];
1395    [invocation setArgument:&object2 atIndex:3];
1396
1397    id returnValue;
1398    @try {
1399        WebThreadCallDelegate(invocation);
1400        if ([[invocation methodSignature] methodReturnLength] == 0) {
1401            return nil;
1402        }
1403        [invocation getReturnValue:&returnValue];
1404        return returnValue;
1405    } @catch(id exception) {
1406        ReportDiscardedDelegateException(selector, exception);
1407    }
1408    return nil;
1409#endif
1410}
1411
1412id CallFormDelegate(WebView *self, SEL selector, id object1, id object2, id object3)
1413{
1414#if !PLATFORM(IOS)
1415    id delegate = self->_private->formDelegate;
1416    if (!delegate || ![delegate respondsToSelector:selector])
1417        return nil;
1418    @try {
1419        return wtfObjcMsgSend<id>(delegate, selector, object1, object2, object3);
1420    } @catch(id exception) {
1421        ReportDiscardedDelegateException(selector, exception);
1422    }
1423    return nil;
1424#else
1425    id delegate = [self _formDelegateForSelector:selector];
1426    if (!delegate)
1427        return nil;
1428
1429    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
1430    [invocation setArgument:&object1 atIndex:2];
1431    [invocation setArgument:&object2 atIndex:3];
1432    [invocation setArgument:&object3 atIndex:4];
1433
1434    id returnValue;
1435    @try {
1436        WebThreadCallDelegate(invocation);
1437        if ([[invocation methodSignature] methodReturnLength] == 0) {
1438            return nil;
1439        }
1440        [invocation getReturnValue:&returnValue];
1441        return returnValue;
1442    } @catch(id exception) {
1443        ReportDiscardedDelegateException(selector, exception);
1444    }
1445    return nil;
1446#endif
1447}
1448
1449id CallFormDelegate(WebView *self, SEL selector, id object1, id object2, id object3, id object4, id object5)
1450{
1451#if !PLATFORM(IOS)
1452    id delegate = self->_private->formDelegate;
1453    if (!delegate || ![delegate respondsToSelector:selector])
1454        return nil;
1455    @try {
1456        return wtfObjcMsgSend<id>(delegate, selector, object1, object2, object3, object4, object5);
1457    } @catch(id exception) {
1458        ReportDiscardedDelegateException(selector, exception);
1459    }
1460    return nil;
1461#else
1462    id delegate = [self _formDelegateForSelector:selector];
1463    if (!delegate)
1464        return nil;
1465
1466    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
1467    [invocation setArgument:&object1 atIndex:2];
1468    [invocation setArgument:&object2 atIndex:3];
1469    [invocation setArgument:&object3 atIndex:4];
1470    [invocation setArgument:&object4 atIndex:5];
1471    [invocation setArgument:&object5 atIndex:6];
1472
1473    id returnValue;
1474    @try {
1475        WebThreadCallDelegate(invocation);
1476        if ([[invocation methodSignature] methodReturnLength] == 0) {
1477            return nil;
1478        }
1479        [invocation getReturnValue:&returnValue];
1480        return returnValue;
1481    } @catch(id exception) {
1482        ReportDiscardedDelegateException(selector, exception);
1483    }
1484    return nil;
1485#endif
1486}
1487
1488BOOL CallFormDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, SEL selectorArg, id object2)
1489{
1490#if !PLATFORM(IOS)
1491    id delegate = self->_private->formDelegate;
1492    if (!delegate || ![delegate respondsToSelector:selector])
1493        return result;
1494    @try {
1495        return wtfObjcMsgSend<BOOL>(delegate, selector, object1, selectorArg, object2);
1496    } @catch(id exception) {
1497        ReportDiscardedDelegateException(selector, exception);
1498    }
1499    return result;
1500#else
1501    id delegate = [self _formDelegateForSelector:selector];
1502    if (!delegate)
1503        return result;
1504
1505    NSInvocation *invocation = WebThreadMakeNSInvocation(delegate, selector);
1506    [invocation setArgument:&object1 atIndex:2];
1507    [invocation setArgument:&selectorArg atIndex:3];
1508    [invocation setArgument:&object2 atIndex:4];
1509
1510    BOOL returnValue;
1511    @try {
1512        WebThreadCallDelegate(invocation);
1513        [invocation getReturnValue:&returnValue];
1514        return returnValue;
1515    } @catch(id exception) {
1516        ReportDiscardedDelegateException(selector, exception);
1517    }
1518    return result;
1519#endif
1520}
1521
1522@end
1523