[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: RFC: [GDL2/base] unableToSetNullForKey: / unableToSetNilForKey:
From: |
David Ayers |
Subject: |
Re: RFC: [GDL2/base] unableToSetNullForKey: / unableToSetNilForKey: |
Date: |
Tue, 25 Mar 2003 00:07:24 +0100 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3b) Gecko/20030210 |
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
- RFC: [GDL2/base] unableToSetNullForKey: / unableToSetNilForKey:, David Ayers, 2003/03/24
- Re[2]: RFC: [GDL2/base] unableToSetNullForKey: / unableToSetNilForKey:, Manuel Guesdon, 2003/03/25
- Re: RFC: [GDL2/base] unableToSetNullForKey: / unableToSetNilForKey:, David Ayers, 2003/03/26
- Re[2]: RFC: [GDL2/base] unableToSetNullForKey: / unableToSetNilForKey:, Manuel Guesdon, 2003/03/26
- Re: RFC: [GDL2/base] unableToSetNullForKey: / unableToSetNilForKey:, David Ayers, 2003/03/26
Re: RFC: [GDL2/base] unableToSetNullForKey: / unableToSetNilForKey:, Manuel Guesdon, 2003/03/25