From 39ff957127ab58ed70161221c7566ad55f408b82 Mon Sep 17 00:00:00 2001 From: ayers Date: Tue, 25 Mar 2003 09:49:39 +0000 Subject: [PATCH] * Headers/gnustep/base/GSObjCRuntime.h * Source/Additions/GSObjCRuntime.m (GSObjCReplaceImplementation): Added new function. * Source/Additions/GSObjCRuntime.m (search_for_method_in_class): Renamed static function for NeXT runtime to better reflect reality. (GSObjCAddMethods): Updated usage. (search_for_method_in_class): New static function for GNU runtime. (flush_method_cache_for_class): New function. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@16252 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 12 ++++++ Headers/gnustep/base/GSObjCRuntime.h | 1 + Source/Additions/GSObjCRuntime.m | 58 ++++++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index d9d971e16..dd19dd97f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2003-03-25 David Ayers + + * Headers/gnustep/base/GSObjCRuntime.h + * Source/Additions/GSObjCRuntime.m (GSObjCReplaceImplementation): + Added new function. + * Source/Additions/GSObjCRuntime.m (search_for_method_in_class): + Renamed static function for NeXT runtime to better reflect + reality. + (GSObjCAddMethods): Updated usage. + (search_for_method_in_class): New static function for GNU runtime. + (flush_method_cache_for_class): New function. + 2003-03-23 Richard Frith-Macdonald * Completed merge of changes from 1.6.0 branch. diff --git a/Headers/gnustep/base/GSObjCRuntime.h b/Headers/gnustep/base/GSObjCRuntime.h index e2d8b8eb2..0b89ebdc0 100644 --- a/Headers/gnustep/base/GSObjCRuntime.h +++ b/Headers/gnustep/base/GSObjCRuntime.h @@ -83,6 +83,7 @@ GS_EXPORT NSArray* GSObjCMethodNames(id obj); GS_EXPORT NSArray* GSObjCVariableNames(id obj); GS_EXPORT void GSObjCAddClassBehavior(Class receiver, Class behavior); +GS_EXPORT IMP GSObjCReplaceImplementation(Class class, SEL sel, IMP imp); GS_EXPORT NSValue* GSObjCMakeClass(NSString *name, NSString *superName, NSDictionary *iVars); diff --git a/Source/Additions/GSObjCRuntime.m b/Source/Additions/GSObjCRuntime.m index 9c2584233..2971290bd 100644 --- a/Source/Additions/GSObjCRuntime.m +++ b/Source/Additions/GSObjCRuntime.m @@ -468,7 +468,7 @@ GSObjCBehaviorDebug(int i) #if NeXT_RUNTIME -static struct objc_method *search_for_method_in_list (Class class, SEL op); +static struct objc_method *search_for_method_in_class (Class class, SEL op); void GSObjCAddMethods (Class class, struct objc_method_list *methods) @@ -504,7 +504,7 @@ GSObjCAddMethods (Class class, struct objc_method_list *methods) sel_get_name(method->method_name)); } - if (!search_for_method_in_list(class,method->method_name) + if (!search_for_method_in_class(class,method->method_name) && !sel_eq(method->method_name, initialize_sel)) { /* As long as the method isn't defined in the CLASS, @@ -537,7 +537,7 @@ GSObjCAddMethods (Class class, struct objc_method_list *methods) /* Search for the named method's method structure. Return a pointer to the method's method structure if found. NULL otherwise. */ static struct objc_method * -search_for_method_in_list (Class class, SEL op) +search_for_method_in_class (Class class, SEL op) { void *iterator = 0; struct objc_method_list *method_list; @@ -574,6 +574,8 @@ search_for_method_in_list (Class class, SEL op) extern Method_t search_for_method_in_list(MethodList_t list, SEL op); extern void class_add_method_list(Class, MethodList_t); +static Method_t search_for_method_in_class (Class class, SEL op); + void GSObjCAddMethods (Class class, struct objc_method_list *methods) { @@ -648,8 +650,58 @@ GSObjCAddMethods (Class class, struct objc_method_list *methods) } } +static Method_t +search_for_method_in_class (Class class, SEL op) +{ + return search_for_method_in_list(class->methods, op); +} + #endif /* NeXT runtime */ +static void +flush_method_cache_for_class (Class class) +{ +#if NeXT_RUNTIME + void _objc_flush_caches (Class cls); + _objc_flush_caches (cls); +#else + void __objc_update_dispatch_table_for_class (Class); + __objc_update_dispatch_table_for_class (class); +#endif +} + +IMP +GSObjCReplaceImplementation (Class class, SEL sel, IMP imp) +{ + struct objc_method *method; + IMP oImp; + + oImp = NULL; + method = search_for_method_in_class (class, sel); + if (method != NULL) + { + oImp = method->method_imp; + method->method_imp = imp; + flush_method_cache_for_class(class); + if (behavior_debug) + { + fprintf(stderr, "replaced implementation for %s in %s.\n", + sel_get_name(sel), class->name); + } + } + else + { + if (behavior_debug) + { + fprintf(stderr, "could not replaced implementation for %s in %s.\n", + sel_get_name(sel), class->name); + } + } + return oImp; +} + + + /** *

A Behavior can be seen as a "Protocol with an implementation" or a * "Class without any instance variables". A key feature of behaviors