From patchwork Fri Oct 15 18:26:11 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: libobjc - Protocol.m moved to modern API From: Nicola Pero X-Patchwork-Id: 67989 Message-Id: <1287167171.084327844@192.168.2.228> To: "gcc-patches@gnu.org" Date: Fri, 15 Oct 2010 20:26:11 +0200 (CEST) This patch continues the move to the modern Objective-C API by migrating Protocol.m to it. It also fixes a tiny inefficiency in the new protocols.c code. Committed to trunk. Thanks 2010-10-15 Nicola Pero * Protocol.m: Include objc/runtime.h and objc-private/module-abi-8.h instead of objc/objc-api.h. Do not repeat Protocol's instance variables. (struct objc_method_description_list): Do not define here. ([-conformsTo:]): Reimplemented on top of protocol_conformsTo(). ([descriptionForInstanceMethod:]): Use sel_isEqual() to compare selectors directly instead of getting names and then using strcmp. ([descriptionForClassMethod:]): Same change. ([-isEqual:]): Reimplemented on top of protocol_isEqual(). * protocols.c (protocol_getMethodDescription): Use sel_isEqual() to compare selectors directly instead of getting names and then using strcmp. * objc/Protocol.h: Updated comments. Index: Protocol.m =================================================================== --- Protocol.m (revision 165499) +++ Protocol.m (working copy) @@ -1,5 +1,5 @@ /* This file contains the implementation of class Protocol. - Copyright (C) 1993, 2004, 2009 Free Software Foundation, Inc. + Copyright (C) 1993, 2004, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -23,69 +23,33 @@ see the files COPYING3 and COPYING.RUNTIME respect . */ #include "objc-private/common.h" +#include "objc/runtime.h" +#include "objc-private/module-abi-8.h" #include "objc/Protocol.h" -#include "objc/objc-api.h" -/* Method description list */ -struct objc_method_description_list { - int count; - struct objc_method_description list[1]; -}; - @implementation Protocol -{ -@private - char *protocol_name; - struct objc_protocol_list *protocol_list; - struct objc_method_description_list *instance_methods, *class_methods; -} -/* Obtaining attributes intrinsic to the protocol */ - - (const char *)name { return protocol_name; } -/* Testing protocol conformance */ - - (BOOL) conformsTo: (Protocol *)aProtocolObject { - size_t i; - struct objc_protocol_list* proto_list; - - if (aProtocolObject == nil) - return NO; - - if (!strcmp(aProtocolObject->protocol_name, self->protocol_name)) - return YES; - - for (proto_list = protocol_list; proto_list; proto_list = proto_list->next) - { - for (i=0; i < proto_list->count; i++) - { - if ([proto_list->list[i] conformsTo: aProtocolObject]) - return YES; - } - } - - return NO; + return protocol_conformsToProtocol (self, aProtocolObject); } -/* Looking up information specific to a protocol */ - - (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel { int i; struct objc_protocol_list* proto_list; - const char* name = sel_get_name (aSel); struct objc_method_description *result; if (instance_methods) for (i = 0; i < instance_methods->count; i++) { - if (!strcmp (sel_get_name (instance_methods->list[i].name), name)) + if (sel_isEqual (instance_methods->list[i].name, aSel)) return &(instance_methods->list[i]); } @@ -95,7 +59,7 @@ see the files COPYING3 and COPYING.RUNTIME respect for (j=0; j < proto_list->count; j++) { if ((result = [proto_list->list[j] - descriptionForInstanceMethod: aSel])) + descriptionForInstanceMethod: aSel])) return result; } } @@ -107,13 +71,12 @@ see the files COPYING3 and COPYING.RUNTIME respect { int i; struct objc_protocol_list* proto_list; - const char* name = sel_get_name (aSel); struct objc_method_description *result; if (class_methods) for (i = 0; i < class_methods->count; i++) { - if (!strcmp (sel_get_name (class_methods->list[i].name), name)) + if (sel_isEqual (class_methods->list[i].name, aSel)) return &(class_methods->list[i]); } @@ -123,7 +86,7 @@ see the files COPYING3 and COPYING.RUNTIME respect for (j=0; j < proto_list->count; j++) { if ((result = [proto_list->list[j] - descriptionForClassMethod: aSel])) + descriptionForClassMethod: aSel])) return result; } } @@ -149,33 +112,9 @@ see the files COPYING3 and COPYING.RUNTIME respect return hash; } -/* - * Equality between formal protocols is only formal (nothing to do - * with actually checking the list of methods they have!). Two formal - * Protocols are equal if and only if they have the same name. - * - * Please note (for comparisons with other implementations) that - * checking the names is equivalent to checking that Protocol A - * conforms to Protocol B and Protocol B conforms to Protocol A, - * because this happens iff they have the same name. If they have - * different names, A conforms to B if and only if A includes B, but - * the situation where A includes B and B includes A is a circular - * dependency between Protocols which is forbidden by the compiler, so - * A conforms to B and B conforms to A with A and B having different - * names is an impossible case. - */ - (BOOL) isEqual: (id)obj { - if (obj == self) - return YES; - - if ([obj isKindOf: [Protocol class]]) - { - if (strcmp (protocol_name, ((Protocol *)obj)->protocol_name) == 0) - return YES; - } - - return NO; + return protocol_isEqual (self, obj); } @end Index: protocols.c =================================================================== --- protocols.c (revision 165499) +++ protocols.c (working copy) @@ -358,7 +358,6 @@ struct objc_method_description protocol_getMethodD BOOL instanceMethod) { struct objc_method_description no_result = { NULL, NULL }; - const char* selector_name; struct objc_method_description_list *methods; int i; @@ -372,8 +371,6 @@ struct objc_method_description protocol_getMethodD if (protocol->class_pointer != objc_lookupClass ("Protocol")) return no_result; - selector_name = sel_getName (selector); - if (instanceMethod) methods = ((struct objc_protocol *)protocol)->instance_methods; else @@ -383,8 +380,12 @@ struct objc_method_description protocol_getMethodD { for (i = 0; i < methods->count; i++) { + if (sel_isEqual (methods->list[i].name, selector)) + return methods->list[i]; + /* if (strcmp (sel_getName (methods->list[i].name), selector_name) == 0) return methods->list[i]; + */ } } Index: ChangeLog =================================================================== --- ChangeLog (revision 165501) +++ ChangeLog (working copy) @@ -1,5 +1,21 @@ 2010-10-15 Nicola Pero + * Protocol.m: Include objc/runtime.h and + objc-private/module-abi-8.h instead of objc/objc-api.h. Do not + repeat Protocol's instance variables. + (struct objc_method_description_list): Do not define here. + ([-conformsTo:]): Reimplemented on top of protocol_conformsTo(). + ([descriptionForInstanceMethod:]): Use sel_isEqual() to compare + selectors directly instead of getting names and then using strcmp. + ([descriptionForClassMethod:]): Same change. + ([-isEqual:]): Reimplemented on top of protocol_isEqual(). + * protocols.c (protocol_getMethodDescription): Use sel_isEqual() + to compare selectors directly instead of getting names and then + using strcmp. + * objc/Protocol.h: Updated comments. + +2010-10-15 Nicola Pero + * init.c (__objc_init_protocol): New function which fixes up a protocol's class pointer, registers it with the runtime, register all protocol selectors and registers associated protocols too. Index: objc/Protocol.h =================================================================== --- objc/Protocol.h (revision 165474) +++ objc/Protocol.h (working copy) @@ -35,21 +35,24 @@ extern "C" { @interface Protocol : Object { @private - char *protocol_name; - struct objc_protocol_list *protocol_list; - struct objc_method_description_list *instance_methods, *class_methods; + char *protocol_name; + struct objc_protocol_list *protocol_list; + struct objc_method_description_list *instance_methods, *class_methods; } +/* The following methods have been replaced by + protocol_getName() + protocol_conformsToProtocol() + protocol_getMethodDescription() +*/ + /* Obtaining attributes intrinsic to the protocol */ - - (const char *)name; /* Testing protocol conformance */ - - (BOOL) conformsTo: (Protocol *)aProtocolObject; /* Looking up information specific to a protocol */ - - (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel; - (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel;