diff options
author | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-10-15 10:35:00 +0000 |
---|---|---|
committer | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-10-15 10:35:00 +0000 |
commit | 1e13b8762fd121ad1d83c8ceb22b8f9dfb98d18c (patch) | |
tree | 25c0b3362de3f254c6fe9987ea63d4a668631f87 /libobjc/init.c | |
parent | 0ba90dfe7ae02bd83235d470f23f095c3ef1eab1 (diff) | |
download | gcc-1e13b8762fd121ad1d83c8ceb22b8f9dfb98d18c.tar.gz |
In libobjc/:
2010-10-14 Nicola Pero <nicola.pero@meta-innovation.com>
* 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.
(objc_init_statics): Detect if we are initializing protocols, and
if so, use __objc_init_protocol instead of only fixing up the
class pointer.
(__objc_init_protocls): Use __objc_init_protocol.
* objc-private/module-abi-8.h: Updated comments.
* objc-private/runtime.h
(__objc_register_selectors_from_description_list): New.
* selector.c (__objc_register_selectors_from_description_list):
New. (struct objc_method_description_list): Declare.
* Protocol.m ([-descriptionForInstanceMethod:]): Use sel_get_name
when accessing the name of a method, which is now correctly a SEL.
([-descriptionForClassMethod:]): Same change.
* protocols.c (protocol_getMethodDescription): Same change.
* objc/runtime.h: Updated comments.
(sel_registerTypedName): Fixed typo in function name.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165499 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libobjc/init.c')
-rw-r--r-- | libobjc/init.c | 92 |
1 files changed, 69 insertions, 23 deletions
diff --git a/libobjc/init.c b/libobjc/init.c index 87122577829..33fb7979ef7 100644 --- a/libobjc/init.c +++ b/libobjc/init.c @@ -32,7 +32,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "objc-private/objc-list.h" #include "objc-private/runtime.h" #include "objc-private/objc-sync.h" /* For __objc_sync_init() */ -#include "objc-private/protocols.h" /* For __objc_protocols_init() and __objc_protocols_add_protocol() */ +#include "objc-private/protocols.h" /* For __objc_protocols_init(), + __objc_protocols_add_protocol() + __objc_protocols_register_selectors() */ /* The version number of this runtime. This must match the number defined in gcc (objc-act.c). */ @@ -70,6 +72,9 @@ static void init_check_module_version (Module_t); /* Assign isa links to protos. */ static void __objc_init_protocols (struct objc_protocol_list *protos); +/* Assign isa link to a protocol, and register it. */ +static void __objc_init_protocol (struct objc_protocol *protocol); + /* Add protocol to class. */ static void __objc_class_add_protocols (Class, struct objc_protocol_list *); @@ -490,11 +495,27 @@ objc_init_statics (void) they were attached to classes or categories, and the class/category loading code automatically fixes them up), and some of them may not. We really need to go - through the whole list to be sure! */ + through the whole list to be sure! Protocols are + also special because we want to register them and + register all their selectors. */ id *inst; - for (inst = &statics->instances[0]; *inst; inst++) - (*inst)->class_pointer = class; + if (strcmp (statics->class_name, "Protocol") == 0) + { + /* Protocols are special, because not only we want + to fix up their class pointers, but we also want + to register them and their selectors with the + runtime. */ + for (inst = &statics->instances[0]; *inst; inst++) + __objc_init_protocol ((struct objc_protocol *)*inst); + } + else + { + /* Other static instances (typically constant strings) are + easier as we just fix up their class pointers. */ + for (inst = &statics->instances[0]; *inst; inst++) + (*inst)->class_pointer = class; + } } } if (module_initialized) @@ -843,6 +864,49 @@ init_check_module_version (Module_t module) } } +/* __objc_init_protocol must be called with __objc_runtime_mutex + already locked, and the "Protocol" class already registered. */ +static void +__objc_init_protocol (struct objc_protocol *protocol) +{ + static Class proto_class = 0; + + if (! proto_class) + proto_class = objc_get_class ("Protocol"); + + if (((size_t)protocol->class_pointer) == PROTOCOL_VERSION) + { + /* Assign class pointer */ + protocol->class_pointer = proto_class; + + /* Register all the selectors in the protocol with the runtime. + This both registers the selectors with the right types, and + it also fixes up the 'struct objc_method' structures inside + the protocol so that each method_name (a char * as compiled + by the compiler) is replaced with the appropriate runtime + SEL. */ + if (protocol->class_methods) + __objc_register_selectors_from_description_list (protocol->class_methods); + + if (protocol->instance_methods) + __objc_register_selectors_from_description_list (protocol->instance_methods); + + /* Register the protocol in the hashtable or protocols by + name. */ + __objc_protocols_add_protocol (protocol->protocol_name, protocol); + + /* Init super protocols */ + __objc_init_protocols (protocol->protocol_list); + } + else if (protocol->class_pointer != proto_class) + { + _objc_abort ("Version %d doesn't match runtime protocol version %d\n", + (int) ((char *) protocol->class_pointer + - (char *) 0), + PROTOCOL_VERSION); + } +} + static void __objc_init_protocols (struct objc_protocol_list *protos) { @@ -871,25 +935,7 @@ __objc_init_protocols (struct objc_protocol_list *protos) for (i = 0; i < protos->count; i++) { struct objc_protocol *aProto = protos->list[i]; - if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION) - { - /* Assign class pointer */ - aProto->class_pointer = proto_class; - - /* Register the protocol in the hashtable or protocols by - name. */ - __objc_protocols_add_protocol (aProto->protocol_name, aProto); - - /* Init super protocols */ - __objc_init_protocols (aProto->protocol_list); - } - else if (protos->list[i]->class_pointer != proto_class) - { - _objc_abort ("Version %d doesn't match runtime protocol version %d\n", - (int) ((char *) protos->list[i]->class_pointer - - (char *) 0), - PROTOCOL_VERSION); - } + __objc_init_protocol (aProto); } objc_mutex_unlock (__objc_runtime_mutex); |