Commit ad248234 by Richard Kenner

(__objc_block_forward): New function.

(get_imp, objc_msg_lookup): Use different forwarding function
when the returning a floating point value.

From-SVN: r12371
parent 7f5648a5
...@@ -49,6 +49,14 @@ static void __objc_install_dispatch_table_for_class (Class); ...@@ -49,6 +49,14 @@ static void __objc_install_dispatch_table_for_class (Class);
/* Forward declare some functions */ /* Forward declare some functions */
static void __objc_init_install_dtable(id, SEL); static void __objc_init_install_dtable(id, SEL);
/* Various forwarding functions that are used based upon the
return type for the selector.
__objc_block_forward for structures.
__objc_double_forward for floats/doubles.
__objc_word_forward for pointers or types that fit in registers.
*/
static double __objc_double_forward(id, SEL, ...);
static id __objc_word_forward(id, SEL, ...); static id __objc_word_forward(id, SEL, ...);
typedef struct { id many[8]; } __big; typedef struct { id many[8]; } __big;
#if INVISIBLE_STRUCT_RETURN #if INVISIBLE_STRUCT_RETURN
...@@ -80,6 +88,8 @@ get_imp (Class class, SEL sel) ...@@ -80,6 +88,8 @@ get_imp (Class class, SEL sel)
const char *t = sel->sel_types; const char *t = sel->sel_types;
if (t && (*t == '[' || *t == '(' || *t == '{')) if (t && (*t == '[' || *t == '(' || *t == '{'))
res = (IMP)__objc_block_forward; res = (IMP)__objc_block_forward;
else if (t && (*t == 'f' || *t == 'd'))
res = (IMP)__objc_double_forward;
else else
res = (IMP)__objc_word_forward; res = (IMP)__objc_word_forward;
} }
...@@ -116,6 +126,8 @@ objc_msg_lookup(id receiver, SEL op) ...@@ -116,6 +126,8 @@ objc_msg_lookup(id receiver, SEL op)
const char *t = op->sel_types; const char *t = op->sel_types;
if (t && (*t == '[' || *t == '(' || *t == '{')) if (t && (*t == '[' || *t == '(' || *t == '{'))
result = (IMP)__objc_block_forward; result = (IMP)__objc_block_forward;
else if (t && (*t == 'f' || *t == 'd'))
result = (IMP)__objc_double_forward;
else else
result = (IMP)__objc_word_forward; result = (IMP)__objc_word_forward;
} }
...@@ -458,6 +470,7 @@ search_for_method_in_list (MethodList_t list, SEL op) ...@@ -458,6 +470,7 @@ search_for_method_in_list (MethodList_t list, SEL op)
static retval_t __objc_forward (id object, SEL sel, arglist_t args); static retval_t __objc_forward (id object, SEL sel, arglist_t args);
/* Forwarding pointers/integers through the normal registers */
static id static id
__objc_word_forward (id rcv, SEL op, ...) __objc_word_forward (id rcv, SEL op, ...)
{ {
...@@ -471,6 +484,21 @@ __objc_word_forward (id rcv, SEL op, ...) ...@@ -471,6 +484,21 @@ __objc_word_forward (id rcv, SEL op, ...)
return res; return res;
} }
/* Specific routine for forwarding floats/double because of
architectural differences on some processors. i386s for
example which uses a floating point stack versus general
registers for floating point numbers. This forward routine
makes sure that GCC restores the proper return values. */
static double
__objc_double_forward (id rcv, SEL op, ...)
{
void *args, *res;
args = __builtin_apply_args ();
res = __objc_forward (rcv, op, args);
__builtin_return (res);
}
#if INVISIBLE_STRUCT_RETURN #if INVISIBLE_STRUCT_RETURN
static __big static __big
#else #else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment