diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1997-03-15 07:57:06 -0500 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1997-03-15 07:57:06 -0500 |
commit | 7084b319a38c009243cfc789180a9a4c6d704a2b (patch) | |
tree | e0ef17f7080bdac946fc093cba6781c1116611c5 /gcc | |
parent | e29e95701bf95580492271e38fc2fe89f9ff9f8f (diff) | |
download | gcc-7084b319a38c009243cfc789180a9a4c6d704a2b.zip gcc-7084b319a38c009243cfc789180a9a4c6d704a2b.tar.gz gcc-7084b319a38c009243cfc789180a9a4c6d704a2b.tar.bz2 |
(class_add_method_list): Check for the +load method when adding a methods list to a class.
(class_add_method_list): Check for the +load method when adding a
methods list to a class.
(__objc_install_methods_in_dtable): New function.
(class_add_method_list): Don't check anymore for duplicate methods.
From-SVN: r13711
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/objc/sendmsg.c | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/gcc/objc/sendmsg.c b/gcc/objc/sendmsg.c index 4d49b35..904a3c4 100644 --- a/gcc/objc/sendmsg.c +++ b/gcc/objc/sendmsg.c @@ -263,7 +263,8 @@ static void __objc_send_initialize(Class class) for (i=0;i<method_list->method_count;i++) { method = &(method_list->method_list[i]); - if (method->method_name->sel_id == op->sel_id) { + if (method->method_name + && method->method_name->sel_id == op->sel_id) { imp = method->method_imp; break; } @@ -280,14 +281,39 @@ static void __objc_send_initialize(Class class) } } -} +} + +/* Walk on the methods list of class and install the methods in the reverse + order of the lists. Since methods added by categories are before the methods + of class in the methods list, this allows categories to substitute methods + declared in class. However if more than one category replace the same method + nothing is guarranteed about what method will be used. + Assumes that __objc_runtime_mutex is locked down. */ +static void +__objc_install_methods_in_dtable (Class class, MethodList_t method_list) +{ + int i; + + if (!method_list) + return; + + if (method_list->method_next) + __objc_install_methods_in_dtable (class, method_list->method_next); + + for (i = 0; i < method_list->method_count; i++) + { + Method_t method = &(method_list->method_list[i]); + sarray_at_put_safe (class->dtable, + (sidx) method->method_name->sel_id, + method->method_imp); + } +} /* Assumes that __objc_runtime_mutex is locked down. */ static void __objc_install_dispatch_table_for_class (Class class) { Class super; - MethodList_t mlist; int counter; /* If the class has not yet had it's class links resolved, we must @@ -310,18 +336,7 @@ __objc_install_dispatch_table_for_class (Class class) else class->dtable = sarray_lazy_copy (super->dtable); - for (mlist = class->methods; mlist; mlist = mlist->method_next) - { - counter = mlist->method_count - 1; - while (counter >= 0) - { - Method_t method = &(mlist->method_list[counter]); - sarray_at_put_safe (class->dtable, - (sidx) method->method_name->sel_id, - method->method_imp); - counter -= 1; - } - } + __objc_install_methods_in_dtable (class, class->methods); } void __objc_update_dispatch_table_for_class (Class class) @@ -361,10 +376,6 @@ void class_add_method_list (Class class, MethodList_t list) { int i; - static SEL initialize_sel = 0; /* !T:SAFE2 */ - - if (!initialize_sel) - initialize_sel = sel_register_name ("initialize"); /* Passing of a linked list is not allowed. Do multiple calls. */ assert (!list->method_next); @@ -380,24 +391,16 @@ class_add_method_list (Class class, MethodList_t list) method->method_name = sel_register_typed_name ((const char*)method->method_name, method->method_types); - - if (search_for_method_in_list (class->methods, method->method_name) - && method->method_name->sel_id != initialize_sel->sel_id) - { - /* Duplication. Print a error message an change the method name - to NULL. */ - fprintf (stderr, "attempt to add a existing method: %s\n", - sel_get_name(method->method_name)); - method->method_name = 0; - } } } /* Add the methods to the class's method list. */ list->method_next = class->methods; class->methods = list; -} + /* Update the dispatch table of class */ + __objc_update_dispatch_table_for_class (class); +} Method_t class_get_instance_method(Class class, SEL op) |