gnustep-dev
[Top][All Lists]
Advanced

[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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]