summaryrefslogtreecommitdiff
path: root/libobjc/init.c
diff options
context:
space:
mode:
authornicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>2010-10-15 10:35:00 +0000
committernicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>2010-10-15 10:35:00 +0000
commit1e13b8762fd121ad1d83c8ceb22b8f9dfb98d18c (patch)
tree25c0b3362de3f254c6fe9987ea63d4a668631f87 /libobjc/init.c
parent0ba90dfe7ae02bd83235d470f23f095c3ef1eab1 (diff)
downloadgcc-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.c92
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);