[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFA/base] GSObjCRuntime (Part 3: Access functions to Method structu
From: |
David Ayers |
Subject: |
Re: [RFA/base] GSObjCRuntime (Part 3: Access functions to Method structures) |
Date: |
Wed, 11 Jun 2003 16:21:34 +0200 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4b) Gecko/20030507 |
Based on Richard's comments, I've decided to name new functions which
- are *not* +load-safe with GSObjC-prefix,
- *are* +load-safe with a simple GS-prefix,
- implement a +load-safe variants of GSObjC functions with GSC-prefix.
This patch only includes new functions which are +load-safe.
Independant of the name the new functions explicitly state whether they
are +load-safe or not. A follow up patch will contain further
documentation about which functions are +load-safe and which are not.
If someone comes up with a better solution please speak up now. :-)
OK, here it is:
* Headers/gnustep/base/objc-gnu2next.h: Remove simple mappings for
class_get_class_method they cannot work due to different
parameter expectations. Added mapping from NeXT->GNU runtime.
The other way does not work. Added simple mapping for internal
flush function __objc_update_dispatch_table_for_class and
_objc_flush_caches.
* Headers/gnustep/base/GSObjCRuntime.h/m:
Added typedef for GSMethod.
(GSGetInstanceMethod): New function.
(GSGetClassMethod): Ditto.
(GSGetInstanceMethodNotInherited): Ditto.
(GSGetClassMethodNotInherited): Ditto.
(GSFlushMethodCacheForClass): Ditto.
(flush_method_cache_for_class): Removed function which is replaced
by GSFlushMethodCacheForClass.
(GSObjCGetMethod): Removed function which is replaced by
GSGetInstanceMethod and GSGetClassMethod.
(GSObjCReplaceMethod): Removed function.
Please note that I have added (or rather renamed and exposed) a function
to invalidate the method cache a class keeps. This patch also includes
a cleanup of objc-gnu2next.h which contained an invalid mapping for
class_get_class_method/call_getClassMethod. It also removes the
superceded imlementations of my previos extensions. Once this patch is
committed, a corresponding patch for GDL2 will also be committed.
Save objections, I will commit this in a couple of days.
Cheers,
David
Index: Headers/gnustep/base/GSObjCRuntime.h
===================================================================
RCS file:
/cvsroot/gnustep/gnustep/core/base/Headers/gnustep/base/GSObjCRuntime.h,v
retrieving revision 1.16
diff -u -r1.16 GSObjCRuntime.h
--- Headers/gnustep/base/GSObjCRuntime.h 7 Jun 2003 17:37:02 -0000
1.16
+++ Headers/gnustep/base/GSObjCRuntime.h 11 Jun 2003 13:51:54 -0000
@@ -1,5 +1,5 @@
/** Interface to ObjC runtime for GNUStep
- Copyright (C) 1995, 1997, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1997, 2000, 2002, 2003 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: 1995
@@ -113,6 +113,14 @@
#include <gnustep/base/objc-gnu2next.h>
+/*
+ * This section includes runtime functions
+ * to query and manipulate the ObjC runtime structures.
+ * These functions take care to not use ObjC code so
+ * that they can safely be used in +(void)load implementations
+ * where applicable.
+ */
+
#define GS_STATIC_INLINE static inline
/*
@@ -261,6 +269,87 @@
return 0;
return sel_get_type(this);
}
+
+
+/*
+ * Unfortunately the definition of the symbol 'Method'
+ * is incompatible between the GNU and NeXT/Apple runtimes.
+ * We introduce GSMethod to allow portability.
+ */
+typedef struct objc_method *GSMethod;
+
+/**
+ * Returns the pointer to the instance method structure
+ * for the selector in the specified class. This function searches
+ * the specified class and its superclasses.<br/>
+ * To obtain the implementation pointer IMP use returnValue->method_imp
+ * which should be safe across all runtimes.<br/>
+ * It should be safe to use this function in +load implementations.
+ */
+GS_STATIC_INLINE GSMethod
+GSGetInstanceMethod(Class class, SEL sel)
+{
+ return class_get_instance_method(class, sel);
+}
+
+/**
+ * Returns the pointer to the instance method structure
+ * for the selector in the specified class. This function searches
+ * the specified class and its superclasses.<br/>
+ * To obtain the implementation pointer IMP use returnValue->method_imp
+ * which should be safe across all runtimes.<br/>
+ * It should be safe to use this function in +load implementations.
+ */
+GS_STATIC_INLINE GSMethod
+GSGetClassMethod(Class class, SEL sel)
+{
+ /*
+ We do not rely on the mapping supplied in objc_gnu2next.h
+ because we want to be explicit about the fact
+ that the expected parameters are different.
+ Therefor we refrain from simply using class_getClassMethod().
+ */
+#ifdef NeXT_RUNTIME
+ return class_getClassMethod(class, sel);
+#else
+ return class_get_class_method(class->class_pointer, sel);
+#endif
+}
+
+/**
+ * Returns the pointer to the instance method structure
+ * for the selector in the specified class. This function only searches
+ * the specified class and not its superclasses.<br/>
+ * To obtain the implementation pointer IMP use returnValue->method_imp
+ * which should be safe across all runtimes.<br/>
+ * It should be safe to use this function in +load implementations.
+ */
+GS_EXPORT GSMethod
+GSGetInstanceMethodNotInherited(Class class, SEL sel);
+
+/**
+ * Returns the pointer to the class method structure
+ * for the selector in the specified class. This function only searches
+ * the specified class and not its superclasses.<br/>
+ * To obtain the implementation pointer IMP use returnValue->method_imp
+ * which should be safe across all runtimes.<br/>
+ * It should be safe to use this function in +load implementations.
+ */
+GS_EXPORT GSMethod
+GSGetClassMethodNotInherited(Class class, SEL sel);
+
+/**
+ * Flushes the cached method dispatch table for the class.
+ * Call this function after any manipulations in the method structures.<br/>
+ * It should be safe to use this function in +load implementations.
+ */
+GS_STATIC_INLINE void
+GSFlushMethodCacheForClass (Class class)
+{
+ extern void __objc_update_dispatch_table_for_class (Class);
+ __objc_update_dispatch_table_for_class (class);
+}
+
GS_STATIC_INLINE Class
Index: Headers/gnustep/base/objc-gnu2next.h
===================================================================
RCS file:
/cvsroot/gnustep/gnustep/core/base/Headers/gnustep/base/objc-gnu2next.h,v
retrieving revision 1.38
diff -u -r1.38 objc-gnu2next.h
--- Headers/gnustep/base/objc-gnu2next.h 3 Mar 2003 10:01:29 -0000
1.38
+++ Headers/gnustep/base/objc-gnu2next.h 11 Jun 2003 13:51:54 -0000
@@ -63,7 +63,6 @@
#define class_create_instance(CLASS) class_createInstance(CLASS, 0)
#define class_get_instance_method class_getInstanceMethod
-#define class_get_class_method class_getClassMethod
#define class_add_method_list class_addMethods
#define class_set_version class_setVersion
#define class_get_version class_getVersion
@@ -79,6 +78,8 @@
#define sel_get_uid sel_getUid
#define sel_eq(s1, s2) (s1 == s2)
+#define __objc_update_dispatch_table_for_class _objc_flush_caches
+
/* There's no support for typed sels in NeXT. These may not work */
#define sel_get_typed_uid(_s, _t) sel_getUid(_s)
#define sel_get_any_typed_uid sel_getUid
@@ -245,7 +246,6 @@
*/
#define class_createInstance(CLASS, X) class_create_instance(CLASS)
#define class_getInstanceMethod class_get_instance_method
-#define class_getClassMethod class_get_class_method
#define class_addMethods class_add_method_list
#define class_setVersion class_set_version
#define class_getVersion class_get_version
@@ -259,6 +259,11 @@
#define sel_getName sel_get_name
#define sel_getUid sel_get_any_uid
+#define _objc_flush_caches __objc_update_dispatch_table_for_class
+
+#define class_getClassMethod(CLASS, SEL) \
+ class_get_class_method((CLASS)->class_pointer, (SEL))
+
#define class_nextMethodList(aClass,anIterator) ({\
if (*(anIterator) == 0) \
*((struct objc_method_list**)(anIterator)) = (aClass)->methods; \
Index: Source/Additions/GSObjCRuntime.m
===================================================================
RCS file: /cvsroot/gnustep/gnustep/core/base/Source/Additions/GSObjCRuntime.m,v
retrieving revision 1.19
diff -u -r1.19 GSObjCRuntime.m
--- Source/Additions/GSObjCRuntime.m 7 Jun 2003 09:45:51 -0000 1.19
+++ Source/Additions/GSObjCRuntime.m 11 Jun 2003 13:51:54 -0000
@@ -659,65 +659,19 @@
#endif /* NeXT runtime */
-static void
-flush_method_cache_for_class (Class class)
+/* See header for documentation. */
+GSMethod
+GSGetInstanceMethodNotInherited (Class class, SEL sel)
{
-#if NeXT_RUNTIME
- void _objc_flush_caches (Class);
- _objc_flush_caches (class);
-#else
- void __objc_update_dispatch_table_for_class (Class);
- __objc_update_dispatch_table_for_class (class);
-#endif
+ return search_for_method_in_class (class, sel);
}
-IMP
-GSObjCGetMethod (Class class, SEL sel)
+/* See header for documentation. */
+GSMethod
+GSGetClassMethodNotInhertited (Class class, SEL sel)
{
- struct objc_method *method;
- IMP imp;
-
- imp = NULL;
- method = search_for_method_in_class (class, sel);
-
- if (method != NULL)
- {
- imp = method->method_imp;
- }
-
- return imp;
-}
-
-IMP
-GSObjCReplaceMethod (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 != NULL ? class->name : "<NULL>");
- }
- }
- return oImp;
+ return search_for_method_in_class (class->class_pointer, sel);
}
-
/**
- [RFA/base] GSObjCRuntime (Part 1: whitespace), David Ayers, 2003/06/05
- Re: [RFA/base] GSObjCRuntime (Part 1: whitespace), Richard Frith-Macdonald, 2003/06/07
- Re: [RFA/base] GSObjCRuntime (Part 2: NO_DEPRECATED macro), David Ayers, 2003/06/07
- Re: [RFA/base] GSObjCRuntime (Part 2: NO_DEPRECATED macro), Richard Frith-Macdonald, 2003/06/11
- Re: [RFA/base] GSObjCRuntime (Part 2: NO_DEPRECATED macro), David Ayers, 2003/06/11
- Re: [RFA/base] GSObjCRuntime (Part 3: Access functions to Method structures),
David Ayers <=
- Re: [RFA/base] GSObjCRuntime (Part 3: Access functions to Method structures), David Ayers, 2003/06/19
- Re: [RFA/base] GSObjCRuntime (Part 3: Access functions to Method structures), David Ayers, 2003/06/22
- Re: [RFA/base] GSObjCRuntime (Part 4: Access IVar definition structures), David Ayers, 2003/06/30