Index: src/runtime/class.m ================================================================== --- src/runtime/class.m +++ src/runtime/class.m @@ -330,129 +330,76 @@ return NULL; } IMP -objc_replace_class_method(Class cls, SEL sel, IMP newimp) -{ - struct objc_method_list *ml; - struct objc_category **cats; - unsigned int i; - BOOL replaced = NO; - IMP oldimp = NULL; - - objc_global_mutex_lock(); - - for (ml = cls->isa->methodlist; ml != NULL; ml = ml->next) { - for (i = 0; i < ml->count; i++) { - if (ml->methods[i].sel.uid == sel->uid) { - oldimp = ml->methods[i].imp; - ml->methods[i].imp = newimp; - replaced = YES; - break; - } - } - } - - if ((cats = objc_categories_for_class(cls)) != NULL) { - for (; *cats != NULL; cats++) { - for (ml = (*cats)->class_methods; ml != NULL; - ml = ml->next) { - for (i = 0; i < ml->count; i++) { - if (ml->methods[i].sel.uid == - sel->uid) { - oldimp = ml->methods[i].imp; - ml->methods[i].imp = newimp; - replaced = YES; - break; - } - } - } - } - } - - if (!replaced) { - /* FIXME: We need a way to free this at objc_exit() */ - if ((ml = malloc(sizeof(struct objc_method_list))) == NULL) - ERROR("Not enough memory to replace method!"); - - ml->next = cls->isa->methodlist; - ml->count = 1; - ml->methods[0].sel.uid = sel->uid; - /* FIXME: We need to get the type from a superclass */ - ml->methods[0].sel.types = sel->types; - ml->methods[0].imp = newimp; - - cls->isa->methodlist = ml; - } - - objc_update_dtable(cls->isa); - - objc_global_mutex_unlock(); - - return oldimp; -} - -IMP -objc_replace_instance_method(Class cls, SEL sel, IMP newimp) -{ - struct objc_method_list *ml; - struct objc_category **cats; - unsigned int i; - BOOL replaced = NO; - IMP oldimp = NULL; +class_replaceMethod(Class cls, SEL sel, IMP newimp, const char *types) +{ + struct objc_method_list *ml; + struct objc_category **cats; + unsigned int i; + IMP oldimp; objc_global_mutex_lock(); for (ml = cls->methodlist; ml != NULL; ml = ml->next) { for (i = 0; i < ml->count; i++) { if (ml->methods[i].sel.uid == sel->uid) { oldimp = ml->methods[i].imp; + ml->methods[i].imp = newimp; - replaced = YES; - break; + objc_update_dtable(cls); + + objc_global_mutex_unlock(); + + return oldimp; } } } if ((cats = objc_categories_for_class(cls)) != NULL) { for (; *cats != NULL; cats++) { - for (ml = (*cats)->instance_methods; ml != NULL; - ml = ml->next) { + if (cls->info & OBJC_CLASS_INFO_METACLASS) + ml = (*cats)->class_methods; + else + ml = (*cats)->instance_methods; + + for (; ml != NULL; ml = ml->next) { for (i = 0; i < ml->count; i++) { if (ml->methods[i].sel.uid == sel->uid) { oldimp = ml->methods[i].imp; + ml->methods[i].imp = newimp; - replaced = YES; - break; + objc_update_dtable(cls); + + objc_global_mutex_unlock(); + + return oldimp; } } } } } - if (!replaced) { - /* FIXME: We need a way to free this at objc_exit() */ - if ((ml = malloc(sizeof(struct objc_method_list))) == NULL) - ERROR("Not enough memory to replace method!"); - - ml->next = cls->methodlist; - ml->count = 1; - ml->methods[0].sel.uid = sel->uid; - /* FIXME: We need to get the type from a superclass */ - ml->methods[0].sel.types = sel->types; - ml->methods[0].imp = newimp; - - cls->methodlist = ml; - } + /* FIXME: We need a way to free this at objc_exit() */ + if ((ml = malloc(sizeof(struct objc_method_list))) == NULL) + ERROR("Not enough memory to replace method!"); + + ml->next = cls->isa->methodlist; + ml->count = 1; + ml->methods[0].sel.uid = sel->uid; + ml->methods[0].sel.types = types; + ml->methods[0].imp = newimp; + + cls->isa->methodlist = ml; objc_update_dtable(cls); objc_global_mutex_unlock(); - return oldimp; + return (IMP)nil; } static void free_class(Class rcls) { Index: src/runtime/runtime.h ================================================================== --- src/runtime/runtime.h +++ src/runtime/runtime.h @@ -108,13 +108,12 @@ extern unsigned long class_getInstanceSize(Class); extern BOOL class_respondsToSelector(Class, SEL); extern BOOL class_conformsToProtocol(Class, Protocol*); extern IMP objc_get_class_method(Class, SEL); extern IMP objc_get_instance_method(Class, SEL); -extern IMP objc_replace_class_method(Class, SEL, IMP); -extern IMP objc_replace_instance_method(Class, SEL, IMP); +extern IMP class_replaceMethod(Class, SEL, IMP, const char*); extern const char* objc_get_type_encoding(Class, SEL); extern IMP objc_msg_lookup(id, SEL); extern void objc_thread_add(void); extern void objc_thread_remove(void); extern void objc_exit(void); #endif