From: Nicola Pero Date: Thu, 23 Dec 2010 06:01:43 +0000 (+0000) Subject: In gcc/: 2010-12-23 Nicola Pero X-Git-Tag: releases/gcc-4.6.0~1640 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=939e4075666396b0653b5650686fd0feccb15b6b;p=gcc.git In gcc/: 2010-12-23 Nicola Pero In gcc/: 2010-12-23 Nicola Pero * doc/objc.texi (Modern GNU Objective-C runtime API): Mention that reference documentation for functions in the API is in the header files. (Messaging with the GNU Objective-C runtime, Dynamically registering methods, Forwarding hook): New sections. From-SVN: r168200 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6beaa7c5175a..c780a7a38050 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-12-23 Nicola Pero + + * doc/objc.texi (Modern GNU Objective-C runtime API): Mention that + reference documentation for functions in the API is in the header + files. + (Messaging with the GNU Objective-C runtime, Dynamically + registering methods, Forwarding hook): New sections. + 2010-12-22 Sebastian Pop PR tree-optimization/47019 diff --git a/gcc/doc/objc.texi b/gcc/doc/objc.texi index ed5d390a84ea..93b5ec513a22 100644 --- a/gcc/doc/objc.texi +++ b/gcc/doc/objc.texi @@ -22,6 +22,7 @@ several resources on the Internet that present the language. * Exceptions:: * Synchronization:: * Fast enumeration:: +* Messaging with the GNU Objective-C runtime:: @end menu @c ========================================================================= @@ -104,6 +105,9 @@ platform-independent set of threading functions. @end itemize +The header files contain detailed documentation for each function in +the GNU Objective-C runtime API. + @c ========================================================================= @node Traditional GNU Objective-C runtime API @subsection Traditional GNU Objective-C runtime API @@ -1086,3 +1090,137 @@ Finally, note how we declared the @code{len} argument and the return value to be of type @code{unsigned long}. They could also be declared to be of type @code{unsigned int} and everything would still work. +@c ========================================================================= +@node Messaging with the GNU Objective-C runtime +@section Messaging with the GNU Objective-C runtime + +This section is specific for the GNU Objective-C runtime. If you are +using a different runtime, you can skip it. + +The implementation of messaging in the GNU Objective-C runtime is +designed to be portable, and so is based on standard C. + +Sending a message in the GNU Objective-C runtime is composed of two +separate steps. First, there is a call to the lookup function, +@code{objc_msg_lookup ()} (or, in the case of messages to super, +@code{objc_msg_lookup_super ()}). This runtime function takes as +argument the receiver and the selector of the method to be called; it +returns the @code{IMP}, that is a pointer to the function implementing +the method. The second step of method invocation consists of casting +this pointer function to the appropriate function pointer type, and +calling the function pointed to it with the right arguments. + +For example, when the compiler encounters a method invocation such as +@code{[object init]}, it compiles it into a call to +@code{objc_msg_lookup (object, @@selector(init))} followed by a cast +of the returned value to the appropriate function pointer type, and +then it calls it. + +@menu +* Dynamically registering methods:: +* Forwarding hook:: +@end menu + +@c ========================================================================= +@node Dynamically registering methods +@subsection Dynamically registering methods + +If @code{objc_msg_lookup()} does not find a suitable method +implementation, because the receiver does not implement the required +method, it tries to see if the class can dynamically register the +method. + +To do so, the runtime checks if the class of the receiver implements +the method + +@smallexample ++ (BOOL) resolveInstanceMethod: (SEL)selector; +@end smallexample + +in the case of an instance method, or + +@smallexample ++ (BOOL) resolveClassMethod: (SEL)selector; +@end smallexample + +in the case of a class method. If the class implements it, the +runtime invokes it, passing as argument the selector of the original +method, and if it returns @code{YES}, the runtime tries the lookup +again, which could now succeed if a matching method was added +dynamically by @code{+resolveInstanceMethod:} or +@code{+resolveClassMethod:}. + +This allows classes to dynamically register methods (by adding them to +the class using @code{class_addMethod}) when they are first called. +To do so, a class should implement @code{+resolveInstanceMethod:} (or, +depending on the case, @code{+resolveClassMethod:}) and have it +recognize the selectors of methods that can be registered dynamically +at runtime, register them, and return @code{YES}. It should return +@code{NO} for methods that it does not dynamically registered at +runtime. + +If @code{+resolveInstanceMethod:} (or @code{+resolveClassMethod:}) is +not implemented or returns @code{NO}, the runtime then tries the +forwarding hook. + +Support for @code{+resolveInstanceMethod:} and +@code{resolveClassMethod:} was added to the GNU Objective-C runtime in +GCC version 4.6. + +@c ========================================================================= +@node Forwarding hook +@subsection Forwarding hook + +The GNU Objective-C runtime provides a hook, called +@code{__objc_msg_forward2}, which is called by +@code{objc_msg_lookup()} when it can't find a method implementation in +the runtime tables and after calling @code{+resolveInstanceMethod:} +and @code{+resolveClassMethod:} has been attempted and did not succeed +in dynamically registering the method. + +To configure the hook, you set the global variable +@code{__objc_msg_foward2} to a function with the same argument and +return types of @code{objc_msg_lookup()}. When +@code{objc_msg_lookup()} can not find a method implementation, it +invokes the hook function you provided to get a method implementation +to return. So, in practice @code{__objc_msg_forward2} allows you to +extend @code{objc_msg_lookup()} by adding some custom code that is +called to do a further lookup when no standard method implementation +can be found using the normal lookup. + +This hook is generally reserved for ``Foundation'' libraries such as +GNUstep Base, which use it to implement their high-level method +forwarding API, typically based around the @code{forwardInvocation:} +method. So, unless you are implementing your own ``Foundation'' +library, you should not set this hook. + +In a typical forwarding implementation, the @code{__objc_msg_forward2} +hook function determines the argument and return type of the method +that is being looked up, and then creates a function that takes these +arguments and has that return type, and returns it to the caller. +Creating this function is non-trivial and is typically performed using +a dedicated library such as @code{libffi}. + +The forwarding method implementation thus created is returned by +@code{objc_msg_lookup()} and is executed as if it was a normal method +implementation. When the forwarding method implementation is called, +it is usually expected to pack all arguments into some sort of object +(typically, an @code{NSInvocation} in a ``Foundation'' library), and +hand it over to the programmer (@code{forwardInvocation:}) who is then +allowed to manipulate the method invocation using a high-level API +provided by the ``Foundation'' library. For example, the programmer +may want to examine the method invocation arguments and name and +potentially change them before forwarding the method invocation to one +or more local objects (@code{performInvocation:}) or even to remote +objects (by using Distributed Objects or some other mechanism). When +all this completes, the return value is passed back and must be +returned correctly to the original caller. + +Note that the GNU Objective-C runtime currently provides no support +for method forwarding or method invocations other than the +@code{__objc_msg_forward2} hook. + +If the forwarding hook does not exist or returns @code{NULL}, the +runtime currently attempts forwarding using an older, deprecated API, +and if that fails, it aborts the program. In future versions of the +GNU Objective-C runtime, the runtime will immediately abort.