In gcc/: 2010-12-23 Nicola Pero <nicola.pero@meta-innovation.com>

In gcc/:
2010-12-23  Nicola Pero  <nicola.pero@meta-innovation.com>

	* 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
This commit is contained in:
Nicola Pero 2010-12-23 06:01:43 +00:00 committed by Nicola Pero
parent 8288398698
commit 939e407566
2 changed files with 146 additions and 0 deletions

View File

@ -1,3 +1,11 @@
2010-12-23 Nicola Pero <nicola.pero@meta-innovation.com>
* 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 <sebastian.pop@amd.com>
PR tree-optimization/47019

View File

@ -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.