improve forwarding hook usage

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/libobjc/trunk@32631 72102866-910b-0410-8b05-ffd578937521
main
rfm 15 years ago
parent e1032243ac
commit 242d634164

@ -139,23 +139,17 @@ __objc_get_forward_imp (id rcv, SEL sel)
Since this requires the dispatch table to be installed, this function
will implicitly invoke +initialize for CLASS if it hasn't been
invoked yet. This also insures that +initialize has been invoked
when the returned implementation is called directly. */
inline
when the returned implementation is called directly.
The forwarding hooks require the receiver as an argument (if they are to
perform dynamic lookup in proxy objects etc), so this function has a
receiver argument to be used with those hooks. */
static inline
IMP
get_imp (Class class, SEL sel)
get_implementation (id receiver, Class class, SEL sel)
{
/* In a vanilla implementation we would first check if the dispatch
table is installed. Here instead, to get more speed in the
standard case (that the dispatch table is installed) we first try
to get the imp using brute force. Only if that fails, we do what
we should have been doing from the very beginning, that is, check
if the dispatch table needs to be installed, install it if it's
not installed, and retrieve the imp from the table if it's
installed. */
void *res = sarray_get_safe (class->dtable, (size_t) sel->sel_id);
if (res == 0)
{
/* Not a valid method */
void *res;
if (class->dtable == __objc_uninstalled_dtable)
{
/* The dispatch table needs to be installed. */
@ -177,12 +171,16 @@ get_imp (Class class, SEL sel)
assert (__objc_prepared_dtable_for_class (class) != 0);
res = __objc_get_prepared_imp (class, sel);
}
else
{
res = 0;
}
objc_mutex_unlock (__objc_runtime_mutex);
/* Call ourselves with the installed dispatch table
and get the real method */
if (! res)
res = get_imp (class, sel);
res = get_implementation (receiver, class, sel);
}
else
{
@ -203,9 +201,28 @@ get_imp (Class class, SEL sel)
We don't know the receiver (only it's class), so we
can't pass that to the function :-(
*/
res = __objc_get_forward_imp (nil, sel);
res = __objc_get_forward_imp (receiver, sel);
}
}
return res;
}
inline
IMP
get_imp (Class class, SEL sel)
{
/* In a vanilla implementation we would first check if the dispatch
table is installed. Here instead, to get more speed in the
standard case (that the dispatch table is installed) we first try
to get the imp using brute force. Only if that fails, we do what
we should have been doing from the very beginning, that is, check
if the dispatch table needs to be installed, install it if it's
not installed, and retrieve the imp from the table if it's
installed. */
void *res = sarray_get_safe (class->dtable, (size_t) sel->sel_id);
if (res == 0)
{
res = get_implementation(nil, class, sel);
}
return res;
}
@ -264,7 +281,7 @@ objc_msg_lookup (id receiver, SEL op)
(sidx)op->sel_id);
if (result == 0)
{
result = get_imp(receiver->class_pointer, op);
result = get_implementation(receiver, receiver->class_pointer, op);
}
return result;
}
@ -586,7 +603,7 @@ __objc_forward (id object, SEL sel, arglist_t args)
if (__objc_responds_to (object, frwd_sel))
{
imp = get_imp (object->class_pointer, frwd_sel);
imp = get_implementation (object, object->class_pointer, frwd_sel);
return (*imp) (object, frwd_sel, sel, args);
}
@ -595,7 +612,7 @@ __objc_forward (id object, SEL sel, arglist_t args)
err_sel = sel_get_any_uid ("doesNotRecognize:");
if (__objc_responds_to (object, err_sel))
{
imp = get_imp (object->class_pointer, err_sel);
imp = get_implementation (object, object->class_pointer, err_sel);
return (*imp) (object, err_sel, sel);
}
@ -614,7 +631,7 @@ __objc_forward (id object, SEL sel, arglist_t args)
err_sel = sel_get_any_uid ("error:");
if (__objc_responds_to (object, err_sel))
{
imp = get_imp (object->class_pointer, err_sel);
imp = get_implementation (object, object->class_pointer, err_sel);
return (*imp) (object, sel_get_any_uid ("error:"), msg);
}
@ -669,7 +686,7 @@ objc_get_uninstalled_dtable ()
static cache_ptr prepared_dtable_table = 0;
/* This function is called by:
get_imp and __objc_responds_to
get_implementation and __objc_responds_to
(and the dispatch table installation functions themselves)
to install a dispatch table for a class.

Loading…
Cancel
Save