Hacks to work around compiler/runtime bugs with protocols.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@17482 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2003-08-15 13:20:50 +00:00
parent 1b684b1fba
commit 541b235438
3 changed files with 86 additions and 31 deletions

View file

@ -1,3 +1,16 @@
2003-08-15 Richard Frith-Macdonald <rfm@gnu.org>
* 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 <d.ayers@inode.at>
* Headers/Additions/GNUstepBase/preface.h: Remove generated

View file

@ -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)
{

View file

@ -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
/**