2017-12-07 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / libobjc / selector.c
blob809e38e1be7f5ff79f2ed17658568e544d24d2de
1 /* GNU Objective C Runtime selector related functions
2 Copyright (C) 1993-2017 Free Software Foundation, Inc.
3 Contributed by Kresten Krab Thorup
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation; either version 3, or (at your option) any later version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 details.
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
25 #include "objc-private/common.h"
26 #include "objc/runtime.h"
27 #include "objc/thr.h"
28 #include "objc-private/hash.h"
29 #include "objc-private/objc-list.h"
30 #include "objc-private/module-abi-8.h"
31 #include "objc-private/runtime.h"
32 #include "objc-private/sarray.h"
33 #include "objc-private/selector.h"
34 #include <stdlib.h> /* For malloc. */
36 /* Initial selector hash table size. Value doesn't matter much. */
37 #define SELECTOR_HASH_SIZE 128
39 /* Tables mapping selector names to uid and opposite. */
40 static struct sarray *__objc_selector_array = 0; /* uid -> sel !T:MUTEX */
41 static struct sarray *__objc_selector_names = 0; /* uid -> name !T:MUTEX */
42 static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */
44 /* Number of selectors stored in each of the above tables. */
45 unsigned int __objc_selector_max_index = 0; /* !T:MUTEX */
47 /* Forward-declare an internal function. */
48 static SEL
49 __sel_register_typed_name (const char *name, const char *types,
50 struct objc_selector *orig, BOOL is_const);
52 void __objc_init_selector_tables (void)
54 __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0);
55 __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0);
56 __objc_selector_hash
57 = objc_hash_new (SELECTOR_HASH_SIZE,
58 (hash_func_type) objc_hash_string,
59 (compare_func_type) objc_compare_strings);
62 /* Register a bunch of selectors from the table of selectors in a
63 module. 'selectors' should not be NULL. The list is terminated by
64 a selectors with a NULL sel_id. The selectors are assumed to
65 contain the 'name' in the sel_id field; this is replaced with the
66 final selector id after they are registered. */
67 void
68 __objc_register_selectors_from_module (struct objc_selector *selectors)
70 int i;
72 for (i = 0; selectors[i].sel_id; ++i)
74 const char *name, *type;
75 name = (char *) selectors[i].sel_id;
76 type = (char *) selectors[i].sel_types;
77 /* Constructors are constant static data and we can safely store
78 pointers to them in the runtime structures, so we set
79 is_const == YES. */
80 __sel_register_typed_name (name, type, (struct objc_selector *) &(selectors[i]),
81 /* is_const */ YES);
85 /* This routine is given a class and records all of the methods in its
86 class structure in the record table. */
87 void
88 __objc_register_selectors_from_class (Class class)
90 struct objc_method_list * method_list;
92 method_list = class->methods;
93 while (method_list)
95 __objc_register_selectors_from_list (method_list);
96 method_list = method_list->method_next;
101 /* This routine is given a list of methods and records each of the
102 methods in the record table. This is the routine that does the
103 actual recording work.
105 The name and type pointers in the method list must be permanent and
106 immutable. */
107 void
108 __objc_register_selectors_from_list (struct objc_method_list *method_list)
110 int i = 0;
112 objc_mutex_lock (__objc_runtime_mutex);
113 while (i < method_list->method_count)
115 Method method = &method_list->method_list[i];
116 if (method->method_name)
118 method->method_name
119 = __sel_register_typed_name ((const char *) method->method_name,
120 method->method_types, 0, YES);
122 i += 1;
124 objc_mutex_unlock (__objc_runtime_mutex);
127 /* The same as __objc_register_selectors_from_list, but works on a
128 struct objc_method_description_list* instead of a struct
129 objc_method_list*. This is only used for protocols, which have
130 lists of method descriptions, not methods. */
131 void
132 __objc_register_selectors_from_description_list
133 (struct objc_method_description_list *method_list)
135 int i = 0;
137 objc_mutex_lock (__objc_runtime_mutex);
138 while (i < method_list->count)
140 struct objc_method_description *method = &method_list->list[i];
141 if (method->name)
143 method->name
144 = __sel_register_typed_name ((const char *) method->name,
145 method->types, 0, YES);
147 i += 1;
149 objc_mutex_unlock (__objc_runtime_mutex);
152 /* Register instance methods as class methods for root classes. */
153 void __objc_register_instance_methods_to_class (Class class)
155 struct objc_method_list *method_list;
156 struct objc_method_list *class_method_list;
157 int max_methods_no = 16;
158 struct objc_method_list *new_list;
159 Method curr_method;
161 /* Only if a root class. */
162 if (class->super_class)
163 return;
165 /* Allocate a method list to hold the new class methods. */
166 new_list = objc_calloc (sizeof (struct objc_method_list)
167 + sizeof (struct objc_method[max_methods_no]), 1);
168 method_list = class->methods;
169 class_method_list = class->class_pointer->methods;
170 curr_method = &new_list->method_list[0];
172 /* Iterate through the method lists for the class. */
173 while (method_list)
175 int i;
177 /* Iterate through the methods from this method list. */
178 for (i = 0; i < method_list->method_count; i++)
180 Method mth = &method_list->method_list[i];
181 if (mth->method_name
182 && ! search_for_method_in_list (class_method_list,
183 mth->method_name))
185 /* This instance method isn't a class method. Add it
186 into the new_list. */
187 *curr_method = *mth;
189 /* Reallocate the method list if necessary. */
190 if (++new_list->method_count == max_methods_no)
191 new_list =
192 objc_realloc (new_list, sizeof (struct objc_method_list)
193 + sizeof (struct
194 objc_method[max_methods_no += 16]));
195 curr_method = &new_list->method_list[new_list->method_count];
199 method_list = method_list->method_next;
202 /* If we created any new class methods then attach the method list
203 to the class. */
204 if (new_list->method_count)
206 new_list =
207 objc_realloc (new_list, sizeof (struct objc_method_list)
208 + sizeof (struct objc_method[new_list->method_count]));
209 new_list->method_next = class->class_pointer->methods;
210 class->class_pointer->methods = new_list;
212 else
213 objc_free(new_list);
215 __objc_update_dispatch_table_for_class (class->class_pointer);
218 BOOL
219 sel_isEqual (SEL s1, SEL s2)
221 if (s1 == 0 || s2 == 0)
222 return s1 == s2;
223 else
224 return s1->sel_id == s2->sel_id;
227 /* Return YES iff t1 and t2 have same method types. Ignore the
228 argframe layout. */
229 static BOOL
230 sel_types_match (const char *t1, const char *t2)
232 if (! t1 || ! t2)
233 return NO;
234 while (*t1 && *t2)
236 if (*t1 == '+') t1++;
237 if (*t2 == '+') t2++;
238 while (isdigit ((unsigned char) *t1)) t1++;
239 while (isdigit ((unsigned char) *t2)) t2++;
240 /* xxx Remove these next two lines when qualifiers are put in
241 all selectors, not just Protocol selectors. */
242 t1 = objc_skip_type_qualifiers (t1);
243 t2 = objc_skip_type_qualifiers (t2);
244 if (! *t1 && ! *t2)
245 return YES;
246 if (*t1 != *t2)
247 return NO;
248 t1++;
249 t2++;
251 return NO;
254 /* Return selector representing name. */
256 sel_get_any_uid (const char *name)
258 struct objc_list *l;
259 sidx i;
261 objc_mutex_lock (__objc_runtime_mutex);
263 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
264 if (soffset_decode (i) == 0)
266 objc_mutex_unlock (__objc_runtime_mutex);
267 return 0;
270 l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
271 objc_mutex_unlock (__objc_runtime_mutex);
273 if (l == 0)
274 return 0;
276 return (SEL) l->head;
280 sel_getTypedSelector (const char *name)
282 sidx i;
284 if (name == NULL)
285 return NULL;
287 objc_mutex_lock (__objc_runtime_mutex);
289 /* Look for a typed selector. */
290 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
291 if (i != 0)
293 struct objc_list *l;
294 SEL returnValue = NULL;
296 for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
297 l; l = l->tail)
299 SEL s = (SEL) l->head;
300 if (s->sel_types)
302 if (returnValue == NULL)
304 /* First typed selector that we find. Keep it in
305 returnValue, but keep checking as we want to
306 detect conflicts. */
307 returnValue = s;
309 else
311 /* We had already found a typed selectors, so we
312 have multiple ones. Double-check that they have
313 different types, just in case for some reason we
314 got duplicates with the same types. If so, it's
315 OK, we'll ignore the duplicate. */
316 if (returnValue->sel_types == s->sel_types)
317 continue;
318 else if (sel_types_match (returnValue->sel_types, s->sel_types))
319 continue;
320 else
322 /* The types of the two selectors are different;
323 it's a conflict. Too bad. Return NULL. */
324 objc_mutex_unlock (__objc_runtime_mutex);
325 return NULL;
331 if (returnValue != NULL)
333 objc_mutex_unlock (__objc_runtime_mutex);
334 return returnValue;
338 /* No typed selector found. Return NULL. */
339 objc_mutex_unlock (__objc_runtime_mutex);
340 return 0;
343 SEL *
344 sel_copyTypedSelectorList (const char *name, unsigned int *numberOfReturnedSelectors)
346 unsigned int count = 0;
347 SEL *returnValue = NULL;
348 sidx i;
350 if (name == NULL)
352 if (numberOfReturnedSelectors)
353 *numberOfReturnedSelectors = 0;
354 return NULL;
357 objc_mutex_lock (__objc_runtime_mutex);
359 /* Count how many selectors we have. */
360 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
361 if (i != 0)
363 struct objc_list *selector_list = NULL;
364 selector_list = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
366 /* Count how many selectors we have. */
368 struct objc_list *l;
369 for (l = selector_list; l; l = l->tail)
370 count++;
373 if (count != 0)
375 /* Allocate enough memory to hold them. */
376 returnValue = (SEL *)(malloc (sizeof (SEL) * (count + 1)));
378 /* Copy the selectors. */
380 unsigned int j;
381 for (j = 0; j < count; j++)
383 returnValue[j] = (SEL)(selector_list->head);
384 selector_list = selector_list->tail;
386 returnValue[j] = NULL;
391 objc_mutex_unlock (__objc_runtime_mutex);
393 if (numberOfReturnedSelectors)
394 *numberOfReturnedSelectors = count;
396 return returnValue;
399 /* Get the name of a selector. If the selector is unknown, the empty
400 string "" is returned. */
401 const char *sel_getName (SEL selector)
403 const char *ret;
405 if (selector == NULL)
406 return "<null selector>";
408 objc_mutex_lock (__objc_runtime_mutex);
409 if ((soffset_decode ((sidx)selector->sel_id) > 0)
410 && (soffset_decode ((sidx)selector->sel_id) <= __objc_selector_max_index))
411 ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id);
412 else
413 ret = 0;
414 objc_mutex_unlock (__objc_runtime_mutex);
415 return ret;
418 BOOL
419 sel_is_mapped (SEL selector)
421 unsigned int idx = soffset_decode ((sidx)selector->sel_id);
422 return ((idx > 0) && (idx <= __objc_selector_max_index));
425 const char *sel_getTypeEncoding (SEL selector)
427 if (selector)
428 return selector->sel_types;
429 else
430 return 0;
433 /* The uninstalled dispatch table. */
434 extern struct sarray *__objc_uninstalled_dtable;
436 /* __sel_register_typed_name allocates lots of struct objc_selector:s
437 of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the
438 number of malloc calls and memory lost to malloc overhead, we
439 allocate objc_selector:s in blocks here. This is only called from
440 __sel_register_typed_name, and __sel_register_typed_name may only
441 be called when __objc_runtime_mutex is locked.
443 Note that the objc_selector:s allocated from
444 __sel_register_typed_name are never freed.
446 62 because 62 * sizeof (struct objc_selector) = 496 (992). This
447 should let malloc add some overhead and use a nice, round 512
448 (1024) byte chunk. */
449 #define SELECTOR_POOL_SIZE 62
450 static struct objc_selector *selector_pool;
451 static int selector_pool_left;
453 static struct objc_selector *
454 pool_alloc_selector(void)
456 if (!selector_pool_left)
458 selector_pool = objc_malloc (sizeof (struct objc_selector)
459 * SELECTOR_POOL_SIZE);
460 selector_pool_left = SELECTOR_POOL_SIZE;
462 return &selector_pool[--selector_pool_left];
465 /* Store the passed selector name in the selector record and return
466 its selector value (value returned by sel_get_uid). Assume that
467 the calling function has locked down __objc_runtime_mutex. The
468 'is_const' parameter tells us if the name and types parameters are
469 really constant or not. If YES then they are constant and we can
470 just store the pointers. If NO then we need to copy name and types
471 because the pointers may disappear later on. If the 'orig'
472 parameter is not NULL, then we are registering a selector from a
473 module, and 'orig' is that selector. In this case, we can put the
474 selector in the tables if needed, and orig->sel_id is updated with
475 the selector ID of the registered selector, and 'orig' is
476 returned. */
477 static SEL
478 __sel_register_typed_name (const char *name, const char *types,
479 struct objc_selector *orig, BOOL is_const)
481 struct objc_selector *j;
482 sidx i;
483 struct objc_list *l;
485 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
486 if (soffset_decode (i) != 0)
488 /* There are already selectors with that name. Examine them to
489 see if the one we're registering already exists. */
490 for (l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
491 l; l = l->tail)
493 SEL s = (SEL)l->head;
494 if (types == 0 || s->sel_types == 0)
496 if (s->sel_types == types)
498 if (orig)
500 orig->sel_id = (void *)i;
501 return orig;
503 else
504 return s;
507 else if (sel_types_match (s->sel_types, types))
509 if (orig)
511 orig->sel_id = (void *)i;
512 return orig;
514 else
515 return s;
518 /* A selector with this specific name/type combination does not
519 exist yet. We need to register it. */
520 if (orig)
521 j = orig;
522 else
523 j = pool_alloc_selector ();
525 j->sel_id = (void *)i;
526 /* Can we use the pointer or must we copy types ? Don't copy if
527 NULL. */
528 if ((is_const) || (types == 0))
529 j->sel_types = types;
530 else
532 j->sel_types = (char *)objc_malloc (strlen (types) + 1);
533 strcpy ((char *)j->sel_types, types);
535 l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
537 else
539 /* There are no other selectors with this name registered in the
540 runtime tables. */
541 const char *new_name;
543 /* Determine i. */
544 __objc_selector_max_index += 1;
545 i = soffset_encode (__objc_selector_max_index);
547 /* Prepare the selector. */
548 if (orig)
549 j = orig;
550 else
551 j = pool_alloc_selector ();
553 j->sel_id = (void *)i;
554 /* Can we use the pointer or must we copy types ? Don't copy if
555 NULL. */
556 if (is_const || (types == 0))
557 j->sel_types = types;
558 else
560 j->sel_types = (char *)objc_malloc (strlen (types) + 1);
561 strcpy ((char *)j->sel_types, types);
564 /* Since this is the first selector with this name, we need to
565 register the correspondence between 'i' (the sel_id) and
566 'name' (the actual string) in __objc_selector_names and
567 __objc_selector_hash. */
569 /* Can we use the pointer or must we copy name ? Don't copy if
570 NULL. (FIXME: Can the name really be NULL here ?) */
571 if (is_const || (name == 0))
572 new_name = name;
573 else
575 new_name = (char *)objc_malloc (strlen (name) + 1);
576 strcpy ((char *)new_name, name);
579 /* This maps the sel_id to the name. */
580 sarray_at_put_safe (__objc_selector_names, i, (void *)new_name);
582 /* This maps the name to the sel_id. */
583 objc_hash_add (&__objc_selector_hash, (void *)new_name, (void *)i);
585 l = 0;
588 DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types,
589 (long)soffset_decode (i));
591 /* Now add the selector to the list of selectors with that id. */
592 l = list_cons ((void *)j, l);
593 sarray_at_put_safe (__objc_selector_array, i, (void *)l);
595 sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
597 return (SEL)j;
601 sel_registerName (const char *name)
603 SEL ret;
605 if (name == NULL)
606 return NULL;
608 objc_mutex_lock (__objc_runtime_mutex);
609 /* Assume that name is not constant static memory and needs to be
610 copied before put into a runtime structure. is_const == NO. */
611 ret = __sel_register_typed_name (name, 0, 0, NO);
612 objc_mutex_unlock (__objc_runtime_mutex);
614 return ret;
618 sel_registerTypedName (const char *name, const char *type)
620 SEL ret;
622 if (name == NULL)
623 return NULL;
625 objc_mutex_lock (__objc_runtime_mutex);
626 /* Assume that name and type are not constant static memory and need
627 to be copied before put into a runtime structure. is_const ==
628 NO. */
629 ret = __sel_register_typed_name (name, type, 0, NO);
630 objc_mutex_unlock (__objc_runtime_mutex);
632 return ret;
635 /* Return the selector representing name. */
637 sel_getUid (const char *name)
639 return sel_registerTypedName (name, 0);