David Ayers wrote:
Should/could we implement something like GSObjCReplaceMethod(Class
class, struct objc_method *old, struct objc_method *new) or should
this be handled differently?
Hi Richard,
I know this is a rather "brutal" approach (but then again so was the
behavior suggestion), yet I believe it should work for both runtimes
and be useful in similar situations. Would you consider the attached
patch as acceptable? If so I would commit.
Cheers,
Dave
PS: And thanks to the folks on irc, who helped me find that runtime
function for the NeXT runtime to clear the method cache.
? core/base/SSL/SSL.bundle
? core/base/SSL/config.log
? core/base/SSL/config.mak
? core/base/SSL/config.status
? core/base/SSL/ix86
? core/base/SSL/shared_obj
? core/base/Source/Additions/shared_obj
? core/base/Tools/make_strings/shared_obj
Index: core/base/Headers/gnustep/base/GSObjCRuntime.h
===================================================================
RCS file:
/cvsroot/gnustep/gnustep/core/base/Headers/gnustep/base/
GSObjCRuntime.h,v
retrieving revision 1.10
diff -u -r1.10 GSObjCRuntime.h
--- core/base/Headers/gnustep/base/GSObjCRuntime.h 2 Mar 2003 10:17:23
-0000 1.10
+++ core/base/Headers/gnustep/base/GSObjCRuntime.h 24 Mar 2003
23:03:10 -0000
@@ -83,6 +83,7 @@
GS_EXPORT NSArray* GSObjCVariableNames(id obj);
GS_EXPORT void GSObjCAddClassBehavior(Class receiver, Class behavior);
+GS_EXPORT void GSObjCReplaceImplementation(Class class, SEL sel, IMP
imp);
GS_EXPORT NSValue*
GSObjCMakeClass(NSString *name, NSString *superName, NSDictionary
*iVars);
Index: core/base/Source/Additions/GSObjCRuntime.m
===================================================================
RCS file:
/cvsroot/gnustep/gnustep/core/base/Source/Additions/GSObjCRuntime.m,v
retrieving revision 1.12
diff -u -r1.12 GSObjCRuntime.m
--- core/base/Source/Additions/GSObjCRuntime.m 23 Mar 2003 07:06:27
-0000 1.12
+++ core/base/Source/Additions/GSObjCRuntime.m 24 Mar 2003 23:03:10
-0000
@@ -468,7 +468,7 @@
#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 @@
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 @@
/* 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 @@
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,7 +650,53 @@
}
}
+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
+}
+
+void
+GSObjCReplaceImplementation (Class class, SEL sel, IMP imp)
+{
+ struct objc_method *method;
+
+ method = search_for_method_in_class (class, sel);
+ if (method != NULL)
+ {
+ 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);
+ }
+ }
+}
+
+
/**
* <p>A Behavior can be seen as a "Protocol with an implementation"
or a
_______________________________________________
Gnustep-dev mailing list
address@hidden
http://mail.gnu.org/mailman/listinfo/gnustep-dev