Andrew Ruder - [PATCH] libobjc __objc_msg_forward2 hook (original) (raw)

This is the mail archive of the gcc-patches@gcc.gnu.orgmailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Hey all,

The __objc_msg_forward hook is quite handy for handling the forwarding in an external library; however, it is often necessary to have a receiver available to determine the IMP to return (this is especially true for wanting to return a ffi_closure from the forwarding hook). It is impossible to determine the correct signature from the selector alone in many circumstances.

The attached (small) patch adds a __objc_msg_forward2 hook to solve this problem. It leaves the __objc_msg_forward hook intact for backwards compatibility reasons; however, the __objc_msg_forward2 hook will be queried first for a forwarding implementation (i.e. its result will be preferred over that of __objc_msg_forward).

Questions/comments/criticisms, let me know.

Thanks, Andy

libobjc/ChangeLog:

2007-02-05 Andrew Ruder andy@aeruder.net

* sendmsg.c: Added __objc_msg_forward2, a hook that allows 
external libraries to provide a function that returns the real
forwarding function based on both the selector and the receiver.

* objc/objc-api.h: Define __objc_msg_forward2

-- Andrew Ruder andy@aeruder.net http://www.aeruder.net

Index: libobjc/sendmsg.c

--- libobjc/sendmsg.c (revision 121568) +++ libobjc/sendmsg.c (working copy) @@ -52,10 +52,15 @@ Boston, MA 02110-1301, USA. / / The uninstalled dispatch table / struct sarray __objc_uninstalled_dtable = 0; / !T:MUTEX / -/ Hook for method forwarding. If it is set, is invoked to return a - function that performs the real forwarding. Otherwise the libgcc - based functions (__builtin_apply and friends) are used. / +/ Two hooks for method forwarding. If either is set, it is invoked + * to return a function that performs the real forwarding. If both + * are set, the result of __objc_msg_forward2 will be preferred over + * that of __objc_msg_forward. If both return NULL or are unset, + * the libgcc based functions (__builtin_apply and friends) are + * used. + / IMP (__objc_msg_forward) (SEL) = NULL; +IMP (__objc_msg_forward2) (id, SEL) = NULL; /* Send +initialize to class / static void __objc_send_initialize (Class); @@ -87,10 +92,18 @@ id nil_method (id, SEL); / Given a selector, return the proper forwarding implementation. / inline IMP -__objc_get_forward_imp (SEL sel) +__objc_get_forward_imp (id rcv, SEL sel) { / If a custom forwarding hook was registered, try getting a forwarding - * function from it. */ + * function from it. There are two forward routine hooks, one that + * takes the receiver as an argument and one that does not. + */ + if (__objc_msg_forward2) + { + IMP result; + if ((result = __objc_msg_forward2 (rcv, sel)) != NULL) + return result; + } if (__objc_msg_forward) { IMP result; @@ -168,7 +181,7 @@ get_imp (Class class, SEL sel) is not in the dispatch table. So the method just doesn't exist for the class. Return the forwarding implementation. / - res = __objc_get_forward_imp (sel); + res = __objc_get_forward_imp ((id)class, sel); } } } @@ -237,7 +250,7 @@ objc_msg_lookup (id receiver, SEL op) { / If the method still just doesn't exist for the class, attempt to forward the method. */ - result = __objc_get_forward_imp (op); + result = __objc_get_forward_imp (receiver, op); } } } Index: libobjc/objc/objc-api.h

--- libobjc/objc/objc-api.h (revision 121568) +++ libobjc/objc/objc-api.h (working copy) @@ -431,11 +431,14 @@ objc_EXPORT void (_objc_calloc)(size_t objc_EXPORT void (_objc_free)(void ); / -* Hook for method forwarding. This makes it easy to substitute a +** Hooks for method forwarding. This makes it easy to substitute a ** library, such as ffcall, that implements closures, thereby avoiding -** gcc's __builtin_apply problems. +** gcc's __builtin_apply problems. __objc_msg_forward2's result will +** be preferred over that of __objc_msg_forward if both are set and +** return non-NULL. / objc_EXPORT IMP (__objc_msg_forward)(SEL); +objc_EXPORT IMP (*__objc_msg_forward2)(id rcv, SEL); Method_t class_get_class_method(MetaClass _class, SEL aSel);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]