diff --git a/ChangeLog b/ChangeLog index d2a06c068..d5affff37 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2003-08-15 Richard Frith-Macdonald + + * Source/NSObject.m: Move hacked methods for getting protocol + method info into functions so we can use them without going + through the ObjC runtime. + * Source/NSDistantObject.m: When attempting to check protocols, + use functions from NSObject.m if the protocol has not been + properly initialised (its class pointer is 0x2) as is the case + for all but very recent versions of the compiler. + FIXME ... this code should be removed at some future date when + all common systems have shipped with a working compiler for + a while. + 2003-08-13 David Ayers * Headers/Additions/GNUstepBase/preface.h: Remove generated diff --git a/Source/NSDistantObject.m b/Source/NSDistantObject.m index a0762b7aa..33833765b 100644 --- a/Source/NSDistantObject.m +++ b/Source/NSDistantObject.m @@ -853,10 +853,34 @@ enum struct objc_method_description* mth; - mth = [_protocol descriptionForInstanceMethod: aSelector]; + /* Older gcc versions may not initialise Protocol objects properly + * so we have an evil hack which checks for a known bad value of + * the class pointer, and uses an internal function + * (implemented in NSObject.m) to examine the protocol contents + * without sending any ObjectiveC message to it. + */ + if ((int)GSObjCClass(_protocol) == 0x2) + { + extern struct objc_method_description* + GSDescriptionForInstanceMethod(); + mth = GSDescriptionForInstanceMethod(_protocol, aSelector); + } + else + { + mth = [_protocol descriptionForInstanceMethod: aSelector]; + } if (mth == 0) { - mth = [_protocol descriptionForClassMethod: aSelector]; + if ((int)GSObjCClass(_protocol) == 0x2) + { + extern struct objc_method_description* + GSDescriptionForClassMethod(); + mth = GSDescriptionForClassMethod(_protocol, aSelector); + } + else + { + mth = [_protocol descriptionForClassMethod: aSelector]; + } } if (mth != 0) { diff --git a/Source/NSObject.m b/Source/NSObject.m index c7c8fb27c..65e575bbc 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -688,70 +688,88 @@ static BOOL double_release_check_enabled = NO; -@implementation Protocol (Fixup) struct objc_method_description_list { - int count; - struct objc_method_description list[1]; + int count; + struct objc_method_description list[1]; }; +typedef struct { + @defs(Protocol) +} *pcl; -- (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel +struct objc_method_description * +GSDescriptionForInstanceMethod(pcl self, SEL aSel) { int i; - struct objc_protocol_list* proto_list; - const char* name = sel_get_name (aSel); + struct objc_protocol_list *p_list; + const char *name = sel_get_name (aSel); struct objc_method_description *result; - if (instance_methods != 0) + if (self->instance_methods != 0) { - for (i = 0; i < instance_methods->count; i++) + for (i = 0; i < self->instance_methods->count; i++) { - if (!strcmp ((char*)instance_methods->list[i].name, name)) - return &(instance_methods->list[i]); + if (!strcmp ((char*)self->instance_methods->list[i].name, name)) + return &(self->instance_methods->list[i]); } } - for (proto_list = protocol_list; proto_list; proto_list = proto_list->next) + for (p_list = self->protocol_list; p_list != 0; p_list = p_list->next) { - size_t j; - for (j=0; j < proto_list->count; j++) + for (i = 0; i < p_list->count; i++) { - if ((result = [proto_list->list[j] - descriptionForInstanceMethod: aSel])) - return result; + result = GSDescriptionForInstanceMethod(p_list->list[i], aSel); + if (result) + { + return result; + } } } return NULL; } -- (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel; +struct objc_method_description * +GSDescriptionForClassMethod(pcl self, SEL aSel) { int i; - struct objc_protocol_list* proto_list; - const char* name = sel_get_name (aSel); + struct objc_protocol_list *p_list; + const char *name = sel_get_name (aSel); struct objc_method_description *result; - if (class_methods != 0) + if (self->class_methods != 0) { - for (i = 0; i < class_methods->count; i++) + for (i = 0; i < self->class_methods->count; i++) { - if (!strcmp ((char*)class_methods->list[i].name, name)) - return &(class_methods->list[i]); + if (!strcmp ((char*)self->class_methods->list[i].name, name)) + return &(self->class_methods->list[i]); } } - for (proto_list = protocol_list; proto_list; proto_list = proto_list->next) + for (p_list = self->protocol_list; p_list != 0; p_list = p_list->next) { - size_t j; - for (j=0; j < proto_list->count; j++) + for (i = 0; i < p_list->count; i++) { - if ((result = [proto_list->list[j] - descriptionForClassMethod: aSel])) - return result; + result = GSDescriptionForClassMethod(p_list->list[i], aSel); + if (result) + { + return result; + } } } return NULL; } +@implementation Protocol (Fixup) + +- (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel +{ + return GSDescriptionForInstanceMethod((pcl)self, aSel); +} + +- (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel; +{ + return GSDescriptionForClassMethod((pcl)self, aSel); +} + @end /**