From 5e5ce83a86599ee9d097ce0f3fc72b5ca2b8a827 Mon Sep 17 00:00:00 2001 From: ayers Date: Sun, 22 Jun 2003 08:45:48 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@16997 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 22 ++++++ Headers/gnustep/base/GSObjCRuntime.h | 110 ++++++++++++++++++++++++++- Headers/gnustep/base/objc-gnu2next.h | 9 ++- Source/Additions/GSObjCRuntime.m | 62 ++------------- 4 files changed, 143 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index cdd7b1796..89da92d2a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2003-06-21 David Ayers + + * 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. + 2003-06-21 Adam Fedor * configure.ac: Check for libkvm. diff --git a/Headers/gnustep/base/GSObjCRuntime.h b/Headers/gnustep/base/GSObjCRuntime.h index aea0baad6..e0cae42aa 100644 --- a/Headers/gnustep/base/GSObjCRuntime.h +++ b/Headers/gnustep/base/GSObjCRuntime.h @@ -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 Date: 1995 @@ -113,6 +113,14 @@ GSObjCSetValue(NSObject *self, NSString *key, id val, SEL sel, #include +/* + * 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 /* @@ -263,6 +271,102 @@ GSTypesFromSelector(SEL 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.
+ * To obtain the implementation pointer IMP use returnValue->method_imp + * which should be safe across all runtimes.
+ * It should be safe to use this function in +load implementations.
+ * This function should currently (June 2003) be considered WIP. + * Please follow potential changes (Name, parameters, ...) closely until + * it stabilizes. + */ +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.
+ * To obtain the implementation pointer IMP use returnValue->method_imp + * which should be safe across all runtimes.
+ * It should be safe to use this function in +load implementations.
+ * This function should currently (June 2003) be considered WIP. + * Please follow potential changes (Name, parameters, ...) closely until + * it stabilizes. + */ +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.
+ * To obtain the implementation pointer IMP use returnValue->method_imp + * which should be safe across all runtimes.
+ * It should be safe to use this function in +load implementations.
+ * This function should currently (June 2003) be considered WIP. + * Please follow potential changes (Name, parameters, ...) closely until + * it stabilizes. + */ +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.
+ * To obtain the implementation pointer IMP use returnValue->method_imp + * which should be safe across all runtimes.
+ * It should be safe to use this function in +load implementations.
+ * This function should currently (June 2003) be considered WIP. + * Please follow potential changes (Name, parameters, ...) closely until + * it stabilizes. + */ +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.
+ * It should be safe to use this function in +load implementations.
+ * This function should currently (June 2003) be considered WIP. + * Please follow potential changes (Name, parameters, ...) closely until + * it stabilizes. + */ +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 GSObjCSuper(Class this) { @@ -300,9 +404,7 @@ GSLastErrorStr(long error_id); #ifndef NO_DEPRECATED -/* - * The next five are old (deprecated) names for the same thing. - */ + GS_EXPORT BOOL GSFindInstanceVariable(id obj, const char *name, const char **type, unsigned int *size, int *offset); diff --git a/Headers/gnustep/base/objc-gnu2next.h b/Headers/gnustep/base/objc-gnu2next.h index fd5df22a8..baf2499ba 100644 --- a/Headers/gnustep/base/objc-gnu2next.h +++ b/Headers/gnustep/base/objc-gnu2next.h @@ -63,7 +63,6 @@ typedef struct objc_super Super; #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 @@ typedef struct objc_super Super; #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 @@ objc_error_handler objc_set_error_handler(objc_error_handler func); */ #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 @@ objc_error_handler objc_set_error_handler(objc_error_handler func); #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; \ diff --git a/Source/Additions/GSObjCRuntime.m b/Source/Additions/GSObjCRuntime.m index 21432c34c..fd94749a1 100644 --- a/Source/Additions/GSObjCRuntime.m +++ b/Source/Additions/GSObjCRuntime.m @@ -659,66 +659,20 @@ search_for_method_in_class (Class class, SEL op) #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; + return search_for_method_in_class (class->class_pointer, sel); } -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 : ""); - } - } - return oImp; -} - - /** *

A Behavior can be seen as a "Protocol with an implementation" or a