]> git.ipfire.org Git - thirdparty/gcc.git/blame - libobjc/selector.c
In gcc/: 2011-05-24 Nicola Pero <nicola.pero@meta-innovation.com>
[thirdparty/gcc.git] / libobjc / selector.c
CommitLineData
88e17b57 1/* GNU Objective C Runtime selector related functions
d652f226
JJ
2 Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004, 2009, 2010
3 Free Software Foundation, Inc.
88e17b57
BE
4 Contributed by Kresten Krab Thorup
5
38709cad 6This file is part of GCC.
88e17b57 7
38709cad 8GCC is free software; you can redistribute it and/or modify it under the
88e17b57 9terms of the GNU General Public License as published by the Free Software
748086b7 10Foundation; either version 3, or (at your option) any later version.
88e17b57 11
38709cad 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
88e17b57
BE
13WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15details.
16
748086b7
JJ
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24<http://www.gnu.org/licenses/>. */
88e17b57 25
6dead247 26#include "objc-private/common.h"
9ecfa8de 27#include "objc/runtime.h"
a19fac96 28#include "objc/thr.h"
5be9cdc1 29#include "objc-private/hash.h"
9ecfa8de
NP
30#include "objc-private/objc-list.h"
31#include "objc-private/module-abi-8.h"
a19fac96 32#include "objc-private/runtime.h"
5d3b14bd 33#include "objc-private/sarray.h"
1af5b8f5 34#include "objc-private/selector.h"
5750872c 35#include <stdlib.h> /* For malloc. */
88e17b57 36
d4645ada 37/* Initial selector hash table size. Value doesn't matter much. */
88e17b57
BE
38#define SELECTOR_HASH_SIZE 128
39
d4645ada 40/* Tables mapping selector names to uid and opposite. */
40165636
RB
41static struct sarray *__objc_selector_array = 0; /* uid -> sel !T:MUTEX */
42static struct sarray *__objc_selector_names = 0; /* uid -> name !T:MUTEX */
88e17b57
BE
43static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */
44
d4645ada 45/* Number of selectors stored in each of the above tables. */
b62cc13a 46unsigned int __objc_selector_max_index = 0; /* !T:MUTEX */
88e17b57 47
600cbba2
NP
48/* Forward-declare an internal function. */
49static SEL
50__sel_register_typed_name (const char *name, const char *types,
51 struct objc_selector *orig, BOOL is_const);
52
64cbe55e 53void __objc_init_selector_tables (void)
88e17b57
BE
54{
55 __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0);
56 __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0);
57 __objc_selector_hash
270a1283
DA
58 = objc_hash_new (SELECTOR_HASH_SIZE,
59 (hash_func_type) objc_hash_string,
60 (compare_func_type) objc_compare_strings);
88e17b57
BE
61}
62
600cbba2
NP
63/* Register a bunch of selectors from the table of selectors in a
64 module. 'selectors' should not be NULL. The list is terminated by
65 a selectors with a NULL sel_id. The selectors are assumed to
66 contain the 'name' in the sel_id field; this is replaced with the
67 final selector id after they are registered. */
68void
69__objc_register_selectors_from_module (struct objc_selector *selectors)
70{
71 int i;
72
73 for (i = 0; selectors[i].sel_id; ++i)
74 {
75 const char *name, *type;
76 name = (char *) selectors[i].sel_id;
77 type = (char *) selectors[i].sel_types;
78 /* Constructors are constant static data and we can safely store
79 pointers to them in the runtime structures, so we set
80 is_const == YES. */
81 __sel_register_typed_name (name, type, (struct objc_selector *) &(selectors[i]),
82 /* is_const */ YES);
83 }
84}
85
d4645ada
NP
86/* This routine is given a class and records all of the methods in its
87 class structure in the record table. */
88e17b57
BE
88void
89__objc_register_selectors_from_class (Class class)
90{
9ecfa8de 91 struct objc_method_list * method_list;
88e17b57
BE
92
93 method_list = class->methods;
94 while (method_list)
95 {
435317e2 96 __objc_register_selectors_from_list (method_list);
88e17b57
BE
97 method_list = method_list->method_next;
98 }
99}
100
101
d4645ada
NP
102/* This routine is given a list of methods and records each of the
103 methods in the record table. This is the routine that does the
104 actual recording work.
88e17b57 105
435317e2 106 The name and type pointers in the method list must be permanent and
d4645ada 107 immutable. */
435317e2 108void
9ecfa8de 109__objc_register_selectors_from_list (struct objc_method_list *method_list)
88e17b57
BE
110{
111 int i = 0;
435317e2
AP
112
113 objc_mutex_lock (__objc_runtime_mutex);
88e17b57
BE
114 while (i < method_list->method_count)
115 {
9ecfa8de 116 Method method = &method_list->method_list[i];
435317e2
AP
117 if (method->method_name)
118 {
119 method->method_name
120 = __sel_register_typed_name ((const char *) method->method_name,
121 method->method_types, 0, YES);
122 }
88e17b57
BE
123 i += 1;
124 }
435317e2 125 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
126}
127
f7185d47
NP
128/* The same as __objc_register_selectors_from_list, but works on a
129 struct objc_method_description_list* instead of a struct
130 objc_method_list*. This is only used for protocols, which have
d4645ada 131 lists of method descriptions, not methods. */
f7185d47
NP
132void
133__objc_register_selectors_from_description_list
134(struct objc_method_description_list *method_list)
135{
136 int i = 0;
137
138 objc_mutex_lock (__objc_runtime_mutex);
139 while (i < method_list->count)
140 {
141 struct objc_method_description *method = &method_list->list[i];
142 if (method->name)
143 {
144 method->name
145 = __sel_register_typed_name ((const char *) method->name,
146 method->types, 0, YES);
147 }
148 i += 1;
149 }
150 objc_mutex_unlock (__objc_runtime_mutex);
151}
88e17b57 152
d4645ada 153/* Register instance methods as class methods for root classes. */
40165636 154void __objc_register_instance_methods_to_class (Class class)
88e17b57 155{
9ecfa8de
NP
156 struct objc_method_list *method_list;
157 struct objc_method_list *class_method_list;
88e17b57 158 int max_methods_no = 16;
9ecfa8de
NP
159 struct objc_method_list *new_list;
160 Method curr_method;
88e17b57
BE
161
162 /* Only if a root class. */
40165636 163 if (class->super_class)
88e17b57
BE
164 return;
165
d4645ada 166 /* Allocate a method list to hold the new class methods. */
40165636 167 new_list = objc_calloc (sizeof (struct objc_method_list)
d4645ada 168 + sizeof (struct objc_method[max_methods_no]), 1);
88e17b57
BE
169 method_list = class->methods;
170 class_method_list = class->class_pointer->methods;
171 curr_method = &new_list->method_list[0];
d4645ada
NP
172
173 /* Iterate through the method lists for the class. */
88e17b57
BE
174 while (method_list)
175 {
176 int i;
d4645ada
NP
177
178 /* Iterate through the methods from this method list. */
88e17b57
BE
179 for (i = 0; i < method_list->method_count; i++)
180 {
9ecfa8de 181 Method mth = &method_list->method_list[i];
88e17b57 182 if (mth->method_name
40165636 183 && ! search_for_method_in_list (class_method_list,
88e17b57
BE
184 mth->method_name))
185 {
d4645ada
NP
186 /* This instance method isn't a class method. Add it
187 into the new_list. */
88e17b57 188 *curr_method = *mth;
d4645ada
NP
189
190 /* Reallocate the method list if necessary. */
40165636 191 if (++new_list->method_count == max_methods_no)
88e17b57 192 new_list =
40165636
RB
193 objc_realloc (new_list, sizeof (struct objc_method_list)
194 + sizeof (struct
d4645ada 195 objc_method[max_methods_no += 16]));
88e17b57
BE
196 curr_method = &new_list->method_list[new_list->method_count];
197 }
198 }
199
200 method_list = method_list->method_next;
201 }
202
d4645ada
NP
203 /* If we created any new class methods then attach the method list
204 to the class. */
88e17b57
BE
205 if (new_list->method_count)
206 {
207 new_list =
40165636 208 objc_realloc (new_list, sizeof (struct objc_method_list)
d4645ada 209 + sizeof (struct objc_method[new_list->method_count]));
88e17b57
BE
210 new_list->method_next = class->class_pointer->methods;
211 class->class_pointer->methods = new_list;
212 }
5af0e6ae
AF
213 else
214 objc_free(new_list);
d4645ada
NP
215
216 __objc_update_dispatch_table_for_class (class->class_pointer);
88e17b57
BE
217}
218
debfbfee
NP
219BOOL
220sel_isEqual (SEL s1, SEL s2)
221{
222 if (s1 == 0 || s2 == 0)
223 return s1 == s2;
224 else
225 return s1->sel_id == s2->sel_id;
226}
88e17b57 227
d4645ada
NP
228/* Return YES iff t1 and t2 have same method types. Ignore the
229 argframe layout. */
88e17b57 230BOOL
40165636 231sel_types_match (const char *t1, const char *t2)
88e17b57 232{
40165636 233 if (! t1 || ! t2)
88e17b57
BE
234 return NO;
235 while (*t1 && *t2)
236 {
237 if (*t1 == '+') t1++;
238 if (*t2 == '+') t2++;
40165636
RB
239 while (isdigit ((unsigned char) *t1)) t1++;
240 while (isdigit ((unsigned char) *t2)) t2++;
88e17b57 241 /* xxx Remove these next two lines when qualifiers are put in
d4645ada 242 all selectors, not just Protocol selectors. */
40165636
RB
243 t1 = objc_skip_type_qualifiers (t1);
244 t2 = objc_skip_type_qualifiers (t2);
245 if (! *t1 && ! *t2)
88e17b57
BE
246 return YES;
247 if (*t1 != *t2)
248 return NO;
249 t1++;
250 t2++;
251 }
252 return NO;
253}
254
5750872c
NP
255/* Return selector representing name. In the Modern API, you'd
256 normally use sel_registerTypedName() for this, which does the same
257 but would register the selector with the runtime if not registered
258 yet (if you only want to check for selectors without registering,
259 use sel_copyTypedSelectorList()). */
88e17b57
BE
260SEL
261sel_get_typed_uid (const char *name, const char *types)
262{
263 struct objc_list *l;
264 sidx i;
265
40165636 266 objc_mutex_lock (__objc_runtime_mutex);
88e17b57 267
270a1283 268 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
88e17b57
BE
269 if (i == 0)
270 {
40165636 271 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
272 return 0;
273 }
274
40165636 275 for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
88e17b57
BE
276 l; l = l->tail)
277 {
40165636 278 SEL s = (SEL) l->head;
88e17b57
BE
279 if (types == 0 || s->sel_types == 0)
280 {
281 if (s->sel_types == types)
282 {
40165636 283 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
284 return s;
285 }
286 }
287 else if (sel_types_match (s->sel_types, types))
288 {
40165636 289 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
290 return s;
291 }
292 }
293
40165636 294 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
295 return 0;
296}
297
d4645ada 298/* Return selector representing name; prefer a selector with non-NULL
5750872c
NP
299 type. In the Modern API, sel_getTypedSelector() is similar but
300 returns NULL if a typed selector couldn't be found. */
88e17b57
BE
301SEL
302sel_get_any_typed_uid (const char *name)
303{
304 struct objc_list *l;
305 sidx i;
306 SEL s = NULL;
307
40165636 308 objc_mutex_lock (__objc_runtime_mutex);
88e17b57 309
270a1283 310 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
88e17b57
BE
311 if (i == 0)
312 {
40165636 313 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
314 return 0;
315 }
316
40165636 317 for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
88e17b57
BE
318 l; l = l->tail)
319 {
320 s = (SEL) l->head;
321 if (s->sel_types)
322 {
48d69c57
NP
323 objc_mutex_unlock (__objc_runtime_mutex);
324 return s;
88e17b57
BE
325 }
326 }
327
40165636 328 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
329 return s;
330}
331
d4645ada 332/* Return selector representing name. */
88e17b57
BE
333SEL
334sel_get_any_uid (const char *name)
335{
336 struct objc_list *l;
337 sidx i;
338
40165636 339 objc_mutex_lock (__objc_runtime_mutex);
88e17b57 340
270a1283 341 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
88e17b57
BE
342 if (soffset_decode (i) == 0)
343 {
40165636 344 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
345 return 0;
346 }
347
40165636
RB
348 l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
349 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
350
351 if (l == 0)
352 return 0;
353
40165636 354 return (SEL) l->head;
88e17b57
BE
355}
356
5750872c
NP
357SEL
358sel_getTypedSelector (const char *name)
359{
360 sidx i;
5750872c 361
9cacfc3e
NP
362 if (name == NULL)
363 return NULL;
364
365 objc_mutex_lock (__objc_runtime_mutex);
366
5750872c
NP
367 /* Look for a typed selector. */
368 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
369 if (i != 0)
370 {
371 struct objc_list *l;
68ade9e4 372 SEL returnValue = NULL;
5750872c
NP
373
374 for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
375 l; l = l->tail)
376 {
377 SEL s = (SEL) l->head;
378 if (s->sel_types)
379 {
68ade9e4
NP
380 if (returnValue == NULL)
381 {
382 /* First typed selector that we find. Keep it in
383 returnValue, but keep checking as we want to
384 detect conflicts. */
385 returnValue = s;
386 }
387 else
388 {
389 /* We had already found a typed selectors, so we
390 have multiple ones. Double-check that they have
391 different types, just in case for some reason we
392 got duplicates with the same types. If so, it's
393 OK, we'll ignore the duplicate. */
394 if (returnValue->sel_types == s->sel_types)
395 continue;
396 else if (sel_types_match (returnValue->sel_types, s->sel_types))
397 continue;
398 else
399 {
400 /* The types of the two selectors are different;
401 it's a conflict. Too bad. Return NULL. */
402 objc_mutex_unlock (__objc_runtime_mutex);
403 return NULL;
404 }
405 }
5750872c
NP
406 }
407 }
68ade9e4
NP
408
409 if (returnValue != NULL)
410 {
411 objc_mutex_unlock (__objc_runtime_mutex);
412 return returnValue;
413 }
5750872c
NP
414 }
415
416 /* No typed selector found. Return NULL. */
417 objc_mutex_unlock (__objc_runtime_mutex);
418 return 0;
419}
420
421SEL *
422sel_copyTypedSelectorList (const char *name, unsigned int *numberOfReturnedSelectors)
423{
424 unsigned int count = 0;
425 SEL *returnValue = NULL;
426 sidx i;
427
428 if (name == NULL)
429 {
430 if (numberOfReturnedSelectors)
431 *numberOfReturnedSelectors = 0;
432 return NULL;
433 }
434
435 objc_mutex_lock (__objc_runtime_mutex);
436
437 /* Count how many selectors we have. */
438 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
439 if (i != 0)
440 {
441 struct objc_list *selector_list = NULL;
442 selector_list = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
443
444 /* Count how many selectors we have. */
445 {
446 struct objc_list *l;
447 for (l = selector_list; l; l = l->tail)
448 count++;
449 }
450
451 if (count != 0)
452 {
453 /* Allocate enough memory to hold them. */
454 returnValue = (SEL *)(malloc (sizeof (SEL) * (count + 1)));
455
456 /* Copy the selectors. */
457 {
458 unsigned int j;
459 for (j = 0; j < count; j++)
460 {
461 returnValue[j] = (SEL)(selector_list->head);
462 selector_list = selector_list->tail;
463 }
464 returnValue[j] = NULL;
465 }
466 }
467 }
468
469 objc_mutex_unlock (__objc_runtime_mutex);
470
471 if (numberOfReturnedSelectors)
472 *numberOfReturnedSelectors = count;
473
474 return returnValue;
475}
476
d4645ada
NP
477/* Get the name of a selector. If the selector is unknown, the empty
478 string "" is returned. */
bc18535a 479const char *sel_getName (SEL selector)
88e17b57
BE
480{
481 const char *ret;
482
524660d2
NP
483 if (selector == NULL)
484 return "<null selector>";
d4645ada 485
40165636
RB
486 objc_mutex_lock (__objc_runtime_mutex);
487 if ((soffset_decode ((sidx)selector->sel_id) > 0)
488 && (soffset_decode ((sidx)selector->sel_id) <= __objc_selector_max_index))
88e17b57
BE
489 ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id);
490 else
491 ret = 0;
40165636 492 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
493 return ret;
494}
495
bc18535a
NP
496/* Traditional GNU Objective-C Runtime API. */
497const char *sel_get_name (SEL selector)
498{
524660d2
NP
499 if (selector == NULL)
500 return 0;
501
bc18535a
NP
502 return sel_getName (selector);
503}
504
88e17b57
BE
505BOOL
506sel_is_mapped (SEL selector)
507{
508 unsigned int idx = soffset_decode ((sidx)selector->sel_id);
509 return ((idx > 0) && (idx <= __objc_selector_max_index));
510}
511
5750872c 512const char *sel_getTypeEncoding (SEL selector)
88e17b57
BE
513{
514 if (selector)
515 return selector->sel_types;
516 else
517 return 0;
518}
519
bc18535a
NP
520/* Traditional GNU Objective-C Runtime API. */
521const char *sel_get_type (SEL selector)
522{
5750872c 523 return sel_getTypeEncoding (selector);
bc18535a
NP
524}
525
d4645ada 526/* The uninstalled dispatch table. */
40165636 527extern struct sarray *__objc_uninstalled_dtable;
88e17b57 528
435317e2 529/* __sel_register_typed_name allocates lots of struct objc_selector:s
d4645ada
NP
530 of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the
531 number of malloc calls and memory lost to malloc overhead, we
532 allocate objc_selector:s in blocks here. This is only called from
533 __sel_register_typed_name, and __sel_register_typed_name may only
534 be called when __objc_runtime_mutex is locked.
535
536 Note that the objc_selector:s allocated from
537 __sel_register_typed_name are never freed.
538
539 62 because 62 * sizeof (struct objc_selector) = 496 (992). This
540 should let malloc add some overhead and use a nice, round 512
541 (1024) byte chunk. */
435317e2
AP
542#define SELECTOR_POOL_SIZE 62
543static struct objc_selector *selector_pool;
544static int selector_pool_left;
545
546static struct objc_selector *
547pool_alloc_selector(void)
548{
549 if (!selector_pool_left)
550 {
551 selector_pool = objc_malloc (sizeof (struct objc_selector)
552 * SELECTOR_POOL_SIZE);
553 selector_pool_left = SELECTOR_POOL_SIZE;
554 }
555 return &selector_pool[--selector_pool_left];
556}
557
d4645ada
NP
558/* Store the passed selector name in the selector record and return
559 its selector value (value returned by sel_get_uid). Assume that
560 the calling function has locked down __objc_runtime_mutex. The
600cbba2 561 'is_const' parameter tells us if the name and types parameters are
d4645ada
NP
562 really constant or not. If YES then they are constant and we can
563 just store the pointers. If NO then we need to copy name and types
600cbba2
NP
564 because the pointers may disappear later on. If the 'orig'
565 parameter is not NULL, then we are registering a selector from a
566 module, and 'orig' is that selector. In this case, we can put the
567 selector in the tables if needed, and orig->sel_id is updated with
568 the selector ID of the registered selector, and 'orig' is
569 returned. */
570static SEL
88e17b57
BE
571__sel_register_typed_name (const char *name, const char *types,
572 struct objc_selector *orig, BOOL is_const)
573{
40165636 574 struct objc_selector *j;
88e17b57
BE
575 sidx i;
576 struct objc_list *l;
577
270a1283 578 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
88e17b57
BE
579 if (soffset_decode (i) != 0)
580 {
c75534d1
NP
581 /* There are already selectors with that name. Examine them to
582 see if the one we're registering already exists. */
583 for (l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
88e17b57
BE
584 l; l = l->tail)
585 {
c75534d1 586 SEL s = (SEL)l->head;
88e17b57
BE
587 if (types == 0 || s->sel_types == 0)
588 {
589 if (s->sel_types == types)
590 {
591 if (orig)
592 {
c75534d1 593 orig->sel_id = (void *)i;
88e17b57
BE
594 return orig;
595 }
596 else
597 return s;
598 }
599 }
40165636 600 else if (! strcmp (s->sel_types, types))
88e17b57
BE
601 {
602 if (orig)
603 {
c75534d1 604 orig->sel_id = (void *)i;
88e17b57
BE
605 return orig;
606 }
607 else
608 return s;
609 }
610 }
c75534d1
NP
611 /* A selector with this specific name/type combination does not
612 exist yet. We need to register it. */
88e17b57
BE
613 if (orig)
614 j = orig;
615 else
435317e2 616 j = pool_alloc_selector ();
d4645ada 617
c75534d1
NP
618 j->sel_id = (void *)i;
619 /* Can we use the pointer or must we copy types ? Don't copy if
d4645ada 620 NULL. */
88e17b57 621 if ((is_const) || (types == 0))
c75534d1 622 j->sel_types = types;
d4645ada
NP
623 else
624 {
c75534d1
NP
625 j->sel_types = (char *)objc_malloc (strlen (types) + 1);
626 strcpy ((char *)j->sel_types, types);
d4645ada 627 }
c75534d1 628 l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
88e17b57
BE
629 }
630 else
631 {
c75534d1
NP
632 /* There are no other selectors with this name registered in the
633 runtime tables. */
634 const char *new_name;
635
636 /* Determine i. */
88e17b57 637 __objc_selector_max_index += 1;
40165636 638 i = soffset_encode (__objc_selector_max_index);
c75534d1
NP
639
640 /* Prepare the selector. */
88e17b57
BE
641 if (orig)
642 j = orig;
643 else
435317e2 644 j = pool_alloc_selector ();
d4645ada 645
c75534d1
NP
646 j->sel_id = (void *)i;
647 /* Can we use the pointer or must we copy types ? Don't copy if
d4645ada 648 NULL. */
c75534d1
NP
649 if (is_const || (types == 0))
650 j->sel_types = types;
651 else
652 {
653 j->sel_types = (char *)objc_malloc (strlen (types) + 1);
654 strcpy ((char *)j->sel_types, types);
655 }
656
657 /* Since this is the first selector with this name, we need to
658 register the correspondence between 'i' (the sel_id) and
659 'name' (the actual string) in __objc_selector_names and
660 __objc_selector_hash. */
661
662 /* Can we use the pointer or must we copy name ? Don't copy if
663 NULL. (FIXME: Can the name really be NULL here ?) */
664 if (is_const || (name == 0))
665 new_name = name;
d4645ada
NP
666 else
667 {
c75534d1
NP
668 new_name = (char *)objc_malloc (strlen (name) + 1);
669 strcpy ((char *)new_name, name);
d4645ada 670 }
c75534d1
NP
671
672 /* This maps the sel_id to the name. */
673 sarray_at_put_safe (__objc_selector_names, i, (void *)new_name);
674
675 /* This maps the name to the sel_id. */
676 objc_hash_add (&__objc_selector_hash, (void *)new_name, (void *)i);
677
88e17b57
BE
678 l = 0;
679 }
680
681 DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types,
c75534d1
NP
682 (long)soffset_decode (i));
683
684 /* Now add the selector to the list of selectors with that id. */
685 l = list_cons ((void *)j, l);
686 sarray_at_put_safe (__objc_selector_array, i, (void *)l);
687
40165636 688 sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
d4645ada 689
c75534d1 690 return (SEL)j;
88e17b57
BE
691}
692
693SEL
bc18535a 694sel_registerName (const char *name)
88e17b57
BE
695{
696 SEL ret;
9cacfc3e
NP
697
698 if (name == NULL)
699 return NULL;
88e17b57 700
40165636 701 objc_mutex_lock (__objc_runtime_mutex);
88e17b57 702 /* Assume that name is not constant static memory and needs to be
d4645ada 703 copied before put into a runtime structure. is_const == NO. */
88e17b57 704 ret = __sel_register_typed_name (name, 0, 0, NO);
40165636 705 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
706
707 return ret;
708}
709
bc18535a 710/* Traditional GNU Objective-C Runtime API. */
88e17b57 711SEL
bc18535a
NP
712sel_register_name (const char *name)
713{
714 return sel_registerName (name);
715}
716
717SEL
718sel_registerTypedName (const char *name, const char *type)
88e17b57
BE
719{
720 SEL ret;
435317e2 721
9cacfc3e
NP
722 if (name == NULL)
723 return NULL;
724
40165636 725 objc_mutex_lock (__objc_runtime_mutex);
d4645ada
NP
726 /* Assume that name and type are not constant static memory and need
727 to be copied before put into a runtime structure. is_const ==
728 NO. */
88e17b57 729 ret = __sel_register_typed_name (name, type, 0, NO);
40165636 730 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
731
732 return ret;
733}
bc18535a
NP
734
735SEL
736sel_register_typed_name (const char *name, const char *type)
737{
738 return sel_registerTypedName (name, type);
739}
740
d4645ada 741/* Return the selector representing name. */
bc18535a
NP
742SEL
743sel_getUid (const char *name)
744{
745 return sel_registerTypedName (name, 0);
746}
747
748/* Traditional GNU Objective-C Runtime API. */
749SEL
750sel_get_uid (const char *name)
751{
752 return sel_getUid (name);
753}