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:
parent
8288398698
commit
939e407566
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user