Home | History | Annotate | Download | only in WebView
      1 /*
      2  * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
      3  * Copyright (C) 2006 David Smith (catfish.man (at) 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 Computer, 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 <objc/objc-runtime.h>
     36 
     37 @implementation WebView (WebDelegateImplementationCaching)
     38 
     39 WebResourceDelegateImplementationCache* WebViewGetResourceLoadDelegateImplementations(WebView *webView)
     40 {
     41     static WebResourceDelegateImplementationCache empty;
     42     if (!webView)
     43         return &empty;
     44     return &webView->_private->resourceLoadDelegateImplementations;
     45 }
     46 
     47 WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementations(WebView *webView)
     48 {
     49     static WebFrameLoadDelegateImplementationCache empty;
     50     if (!webView)
     51         return &empty;
     52     return &webView->_private->frameLoadDelegateImplementations;
     53 }
     54 
     55 WebScriptDebugDelegateImplementationCache* WebViewGetScriptDebugDelegateImplementations(WebView *webView)
     56 {
     57     static WebScriptDebugDelegateImplementationCache empty;
     58     if (!webView)
     59         return &empty;
     60     return &webView->_private->scriptDebugDelegateImplementations;
     61 }
     62 
     63 WebHistoryDelegateImplementationCache* WebViewGetHistoryDelegateImplementations(WebView *webView)
     64 {
     65     static WebHistoryDelegateImplementationCache empty;
     66     if (!webView)
     67         return &empty;
     68     return &webView->_private->historyDelegateImplementations;
     69 }
     70 
     71 // We use these functions to call the delegates and block exceptions. These functions are
     72 // declared inside a WebView category to get direct access to the delegate data memebers,
     73 // preventing more ObjC message dispatch and compensating for the expense of the @try/@catch.
     74 
     75 typedef float (*ObjCMsgSendFPRet)(id, SEL, ...);
     76 #if defined(__i386__)
     77 static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend_fpret);
     78 #else
     79 static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend);
     80 #endif
     81 
     82 static inline id CallDelegate(WebView *self, id delegate, SEL selector)
     83 {
     84     if (!delegate || ![delegate respondsToSelector:selector])
     85         return nil;
     86     if (!self->_private->catchesDelegateExceptions)
     87         return objc_msgSend(delegate, selector, self);
     88     @try {
     89         return objc_msgSend(delegate, selector, self);
     90     } @catch(id exception) {
     91         ReportDiscardedDelegateException(selector, exception);
     92     }
     93     return nil;
     94 }
     95 
     96 static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object)
     97 {
     98     if (!delegate || ![delegate respondsToSelector:selector])
     99         return nil;
    100     if (!self->_private->catchesDelegateExceptions)
    101         return objc_msgSend(delegate, selector, self, object);
    102     @try {
    103         return objc_msgSend(delegate, selector, self, object);
    104     } @catch(id exception) {
    105         ReportDiscardedDelegateException(selector, exception);
    106     }
    107     return nil;
    108 }
    109 
    110 static inline id CallDelegate(WebView *self, id delegate, SEL selector, NSRect rect)
    111 {
    112     if (!delegate || ![delegate respondsToSelector:selector])
    113         return nil;
    114     if (!self->_private->catchesDelegateExceptions)
    115         return reinterpret_cast<id (*)(id, SEL, WebView *, NSRect)>(objc_msgSend)(delegate, selector, self, rect);
    116     @try {
    117         return reinterpret_cast<id (*)(id, SEL, WebView *, NSRect)>(objc_msgSend)(delegate, selector, self, rect);
    118     } @catch(id exception) {
    119         ReportDiscardedDelegateException(selector, exception);
    120     }
    121     return nil;
    122 }
    123 
    124 static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2)
    125 {
    126     if (!delegate || ![delegate respondsToSelector:selector])
    127         return nil;
    128     if (!self->_private->catchesDelegateExceptions)
    129         return objc_msgSend(delegate, selector, self, object1, object2);
    130     @try {
    131         return objc_msgSend(delegate, selector, self, object1, object2);
    132     } @catch(id exception) {
    133         ReportDiscardedDelegateException(selector, exception);
    134     }
    135     return nil;
    136 }
    137 
    138 static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, BOOL boolean)
    139 {
    140     if (!delegate || ![delegate respondsToSelector:selector])
    141         return nil;
    142     if (!self->_private->catchesDelegateExceptions)
    143         return objc_msgSend(delegate, selector, self, object, boolean);
    144     @try {
    145         return objc_msgSend(delegate, selector, self, object, boolean);
    146     } @catch(id exception) {
    147         ReportDiscardedDelegateException(selector, exception);
    148     }
    149     return nil;
    150 }
    151 
    152 static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
    153 {
    154     if (!delegate || ![delegate respondsToSelector:selector])
    155         return nil;
    156     if (!self->_private->catchesDelegateExceptions)
    157         return objc_msgSend(delegate, selector, self, object1, object2, object3);
    158     @try {
    159         return objc_msgSend(delegate, selector, self, object1, object2, object3);
    160     } @catch(id exception) {
    161         ReportDiscardedDelegateException(selector, exception);
    162     }
    163     return nil;
    164 }
    165 
    166 static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, NSUInteger integer)
    167 {
    168     if (!delegate || ![delegate respondsToSelector:selector])
    169         return nil;
    170     if (!self->_private->catchesDelegateExceptions)
    171         return objc_msgSend(delegate, selector, self, object, integer);
    172     @try {
    173         return objc_msgSend(delegate, selector, self, object, integer);
    174     } @catch(id exception) {
    175         ReportDiscardedDelegateException(selector, exception);
    176     }
    177     return nil;
    178 }
    179 
    180 static inline float CallDelegateReturningFloat(WebView *self, id delegate, SEL selector)
    181 {
    182     if (!delegate || ![delegate respondsToSelector:selector])
    183         return 0.0f;
    184     if (!self->_private->catchesDelegateExceptions)
    185         return objc_msgSend_float_return(delegate, selector, self);
    186     @try {
    187         return objc_msgSend_float_return(delegate, selector, self);
    188     } @catch(id exception) {
    189         ReportDiscardedDelegateException(selector, exception);
    190     }
    191     return 0.0f;
    192 }
    193 
    194 static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector)
    195 {
    196     if (!delegate || ![delegate respondsToSelector:selector])
    197         return result;
    198     if (!self->_private->catchesDelegateExceptions)
    199         return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)(delegate, selector, self);
    200     @try {
    201         return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)(delegate, selector, self);
    202     } @catch(id exception) {
    203         ReportDiscardedDelegateException(selector, exception);
    204     }
    205     return result;
    206 }
    207 
    208 static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object)
    209 {
    210     if (!delegate || ![delegate respondsToSelector:selector])
    211         return result;
    212     if (!self->_private->catchesDelegateExceptions)
    213         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id)>(objc_msgSend)(delegate, selector, self, object);
    214     @try {
    215         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id)>(objc_msgSend)(delegate, selector, self, object);
    216     } @catch(id exception) {
    217         ReportDiscardedDelegateException(selector, exception);
    218     }
    219     return result;
    220 }
    221 
    222 static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object, BOOL boolean)
    223 {
    224     if (!delegate || ![delegate respondsToSelector:selector])
    225         return result;
    226     if (!self->_private->catchesDelegateExceptions)
    227         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL)>(objc_msgSend)(delegate, selector, self, object, boolean);
    228     @try {
    229         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL)>(objc_msgSend)(delegate, selector, self, object, boolean);
    230     } @catch(id exception) {
    231         ReportDiscardedDelegateException(selector, exception);
    232     }
    233     return result;
    234 }
    235 
    236 static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object, BOOL boolean, id object2)
    237 {
    238     if (!delegate || ![delegate respondsToSelector:selector])
    239         return result;
    240     if (!self->_private->catchesDelegateExceptions)
    241         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL, id)>(objc_msgSend)(delegate, selector, self, object, boolean, object2);
    242     @try {
    243         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL, id)>(objc_msgSend)(delegate, selector, self, object, boolean, object2);
    244     } @catch(id exception) {
    245         ReportDiscardedDelegateException(selector, exception);
    246     }
    247     return result;
    248 }
    249 
    250 static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object1, id object2)
    251 {
    252     if (!delegate || ![delegate respondsToSelector:selector])
    253         return result;
    254     if (!self->_private->catchesDelegateExceptions)
    255         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(delegate, selector, self, object1, object2);
    256     @try {
    257         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(delegate, selector, self, object1, object2);
    258     } @catch(id exception) {
    259         ReportDiscardedDelegateException(selector, exception);
    260     }
    261     return result;
    262 }
    263 
    264 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector)
    265 {
    266     if (!delegate)
    267         return nil;
    268     if (!self->_private->catchesDelegateExceptions)
    269         return implementation(delegate, selector, self);
    270     @try {
    271         return implementation(delegate, selector, self);
    272     } @catch(id exception) {
    273         ReportDiscardedDelegateException(selector, exception);
    274     }
    275     return nil;
    276 }
    277 
    278 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object)
    279 {
    280     if (!delegate)
    281         return nil;
    282     if (!self->_private->catchesDelegateExceptions)
    283         return implementation(delegate, selector, self, object);
    284     @try {
    285         return implementation(delegate, selector, self, object);
    286     } @catch(id exception) {
    287         ReportDiscardedDelegateException(selector, exception);
    288     }
    289     return nil;
    290 }
    291 
    292 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2)
    293 {
    294     if (!delegate)
    295         return nil;
    296     if (!self->_private->catchesDelegateExceptions)
    297         return implementation(delegate, selector, self, object1, object2);
    298     @try {
    299         return implementation(delegate, selector, self, object1, object2);
    300     } @catch(id exception) {
    301         ReportDiscardedDelegateException(selector, exception);
    302     }
    303     return nil;
    304 }
    305 
    306 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3)
    307 {
    308     if (!delegate)
    309         return nil;
    310     if (!self->_private->catchesDelegateExceptions)
    311         return implementation(delegate, selector, self, object1, object2, object3);
    312     @try {
    313         return implementation(delegate, selector, self, object1, object2, object3);
    314     } @catch(id exception) {
    315         ReportDiscardedDelegateException(selector, exception);
    316     }
    317     return nil;
    318 }
    319 
    320 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3, id object4)
    321 {
    322     if (!delegate)
    323         return nil;
    324     if (!self->_private->catchesDelegateExceptions)
    325         return implementation(delegate, selector, self, object1, object2, object3, object4);
    326     @try {
    327         return implementation(delegate, selector, self, object1, object2, object3, object4);
    328     } @catch(id exception) {
    329         ReportDiscardedDelegateException(selector, exception);
    330     }
    331     return nil;
    332 }
    333 
    334 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2)
    335 {
    336     if (!delegate)
    337         return nil;
    338     if (!self->_private->catchesDelegateExceptions)
    339         return implementation(delegate, selector, self, object1, integer, object2);
    340     @try {
    341         return implementation(delegate, selector, self, object1, integer, object2);
    342     } @catch(id exception) {
    343         ReportDiscardedDelegateException(selector, exception);
    344     }
    345     return nil;
    346 }
    347 
    348 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, NSInteger integer2, id object2)
    349 {
    350     if (!delegate)
    351         return nil;
    352     if (!self->_private->catchesDelegateExceptions)
    353         return implementation(delegate, selector, self, object1, integer1, integer2, object2);
    354     @try {
    355         return implementation(delegate, selector, self, object1, integer1, integer2, object2);
    356     } @catch(id exception) {
    357         ReportDiscardedDelegateException(selector, exception);
    358     }
    359     return nil;
    360 }
    361 
    362 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, NSInteger integer, id object3)
    363 {
    364     if (!delegate)
    365         return nil;
    366     if (!self->_private->catchesDelegateExceptions)
    367         return implementation(delegate, selector, self, object1, object2, integer, object3);
    368     @try {
    369         return implementation(delegate, selector, self, object1, object2, integer, object3);
    370     } @catch(id exception) {
    371         ReportDiscardedDelegateException(selector, exception);
    372     }
    373     return nil;
    374 }
    375 
    376 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3)
    377 {
    378     if (!delegate)
    379         return nil;
    380     if (!self->_private->catchesDelegateExceptions)
    381         return implementation(delegate, selector, self, object1, integer1, object2, integer2, object3);
    382     @try {
    383         return implementation(delegate, selector, self, object1, integer1, object2, integer2, object3);
    384     } @catch(id exception) {
    385         ReportDiscardedDelegateException(selector, exception);
    386     }
    387     return nil;
    388 }
    389 
    390 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4)
    391 {
    392     if (!delegate)
    393         return nil;
    394     if (!self->_private->catchesDelegateExceptions)
    395         return implementation(delegate, selector, self, object1, integer, object2, object3, object4);
    396     @try {
    397         return implementation(delegate, selector, self, object1, integer, object2, object3, object4);
    398     } @catch(id exception) {
    399         ReportDiscardedDelegateException(selector, exception);
    400     }
    401     return nil;
    402 }
    403 
    404 static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSTimeInterval interval, id object2, id object3)
    405 {
    406     if (!delegate)
    407         return nil;
    408     if (!self->_private->catchesDelegateExceptions)
    409         return implementation(delegate, selector, self, object1, interval, object2, object3);
    410     @try {
    411         return implementation(delegate, selector, self, object1, interval, object2, object3);
    412     } @catch(id exception) {
    413         ReportDiscardedDelegateException(selector, exception);
    414     }
    415     return nil;
    416 }
    417 
    418 id CallUIDelegate(WebView *self, SEL selector)
    419 {
    420     return CallDelegate(self, self->_private->UIDelegate, selector);
    421 }
    422 
    423 id CallUIDelegate(WebView *self, SEL selector, id object)
    424 {
    425     return CallDelegate(self, self->_private->UIDelegate, selector, object);
    426 }
    427 
    428 id CallUIDelegate(WebView *self, SEL selector, id object, BOOL boolean)
    429 {
    430     return CallDelegate(self, self->_private->UIDelegate, selector, object, boolean);
    431 }
    432 
    433 id CallUIDelegate(WebView *self, SEL selector, NSRect rect)
    434 {
    435     return CallDelegate(self, self->_private->UIDelegate, selector, rect);
    436 }
    437 
    438 id CallUIDelegate(WebView *self, SEL selector, id object1, id object2)
    439 {
    440     return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2);
    441 }
    442 
    443 id CallUIDelegate(WebView *self, SEL selector, id object1, id object2, id object3)
    444 {
    445     return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2, object3);
    446 }
    447 
    448 id CallUIDelegate(WebView *self, SEL selector, id object, NSUInteger integer)
    449 {
    450     return CallDelegate(self, self->_private->UIDelegate, selector, object, integer);
    451 }
    452 
    453 float CallUIDelegateReturningFloat(WebView *self, SEL selector)
    454 {
    455     return CallDelegateReturningFloat(self, self->_private->UIDelegate, selector);
    456 }
    457 
    458 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector)
    459 {
    460     return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector);
    461 }
    462 
    463 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object)
    464 {
    465     return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object);
    466 }
    467 
    468 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean)
    469 {
    470     return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean);
    471 }
    472 
    473 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean, id object2)
    474 {
    475     return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean, object2);
    476 }
    477 
    478 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, id object2)
    479 {
    480     return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object1, object2);
    481 }
    482 
    483 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector)
    484 {
    485     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector);
    486 }
    487 
    488 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object)
    489 {
    490     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object);
    491 }
    492 
    493 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
    494 {
    495     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2);
    496 }
    497 
    498 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
    499 {
    500     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3);
    501 }
    502 
    503 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
    504 {
    505     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3, object4);
    506 }
    507 
    508 id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSTimeInterval interval, id object2, id object3)
    509 {
    510     return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, interval, object2, object3);
    511 }
    512 
    513 id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
    514 {
    515     return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2);
    516 }
    517 
    518 id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
    519 {
    520     return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3);
    521 }
    522 
    523 id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4)
    524 {
    525     return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3, object4);
    526 }
    527 
    528 id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2)
    529 {
    530     return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, integer, object2);
    531 }
    532 
    533 id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3)
    534 {
    535     return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, integer, object3);
    536 }
    537 
    538 BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1, id object2)
    539 {
    540     if (!self->_private->catchesDelegateExceptions)
    541         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2);
    542     @try {
    543         return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2);
    544     } @catch(id exception) {
    545         ReportDiscardedDelegateException(selector, exception);
    546     }
    547     return result;
    548 }
    549 
    550 id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3)
    551 {
    552     return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, object2, integer, object3);
    553 }
    554 
    555 id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3)
    556 {
    557     return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, object2, integer2, object3);
    558 }
    559 
    560 id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4)
    561 {
    562     return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer, object2, object3, object4);
    563 }
    564 
    565 id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, NSInteger integer2, id object2)
    566 {
    567     return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, integer2, object2);
    568 }
    569 
    570 id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector)
    571 {
    572     return CallDelegate(implementation, self, self->_private->historyDelegate, selector);
    573 }
    574 
    575 id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
    576 {
    577     return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2);
    578 }
    579 
    580 id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
    581 {
    582     return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2, object3);
    583 }
    584 
    585 // The form delegate needs to have it's own implementation, because the first argument is never the WebView
    586 
    587 id CallFormDelegate(WebView *self, SEL selector, id object1, id object2)
    588 {
    589     id delegate = self->_private->formDelegate;
    590     if (!delegate || ![delegate respondsToSelector:selector])
    591         return nil;
    592     if (!self->_private->catchesDelegateExceptions)
    593         return objc_msgSend(delegate, selector, object1, object2);
    594     @try {
    595         return objc_msgSend(delegate, selector, object1, object2);
    596     } @catch(id exception) {
    597         ReportDiscardedDelegateException(selector, exception);
    598     }
    599     return nil;
    600 }
    601 
    602 id CallFormDelegate(WebView *self, SEL selector, id object1, id object2, id object3, id object4, id object5)
    603 {
    604     id delegate = self->_private->formDelegate;
    605     if (!delegate || ![delegate respondsToSelector:selector])
    606         return nil;
    607     if (!self->_private->catchesDelegateExceptions)
    608         return objc_msgSend(delegate, selector, object1, object2, object3, object4, object5);
    609     @try {
    610         return objc_msgSend(delegate, selector, object1, object2, object3, object4, object5);
    611     } @catch(id exception) {
    612         ReportDiscardedDelegateException(selector, exception);
    613     }
    614     return nil;
    615 }
    616 
    617 BOOL CallFormDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, SEL selectorArg, id object2)
    618 {
    619     id delegate = self->_private->formDelegate;
    620     if (!delegate || ![delegate respondsToSelector:selector])
    621         return result;
    622     if (!self->_private->catchesDelegateExceptions)
    623         return reinterpret_cast<BOOL (*)(id, SEL, id, SEL, id)>(objc_msgSend)(delegate, selector, object1, selectorArg, object2);
    624     @try {
    625         return reinterpret_cast<BOOL (*)(id, SEL, id, SEL, id)>(objc_msgSend)(delegate, selector, object1, selectorArg, object2);
    626     } @catch(id exception) {
    627         ReportDiscardedDelegateException(selector, exception);
    628     }
    629     return result;
    630 }
    631 
    632 @end
    633