Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libobjc / selector.c
blob0e51e31b132e1cb3fa24f166072f96c82afb39db
1 /* GNU Objective C Runtime selector related functions
2 Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004, 2009 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"
34 /* Initial selector hash table size. Value doesn't matter much. */
35 #define SELECTOR_HASH_SIZE 128
37 /* Tables mapping selector names to uid and opposite. */
38 static struct sarray *__objc_selector_array = 0; /* uid -> sel !T:MUTEX */
39 static struct sarray *__objc_selector_names = 0; /* uid -> name !T:MUTEX */
40 static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */
42 /* Number of selectors stored in each of the above tables. */
43 unsigned int __objc_selector_max_index = 0; /* !T:MUTEX */
45 void __objc_init_selector_tables (void)
47 __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0);
48 __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0);
49 __objc_selector_hash
50 = objc_hash_new (SELECTOR_HASH_SIZE,
51 (hash_func_type) objc_hash_string,
52 (compare_func_type) objc_compare_strings);
55 /* This routine is given a class and records all of the methods in its
56 class structure in the record table. */
57 void
58 __objc_register_selectors_from_class (Class class)
60 struct objc_method_list * method_list;
62 method_list = class->methods;
63 while (method_list)
65 __objc_register_selectors_from_list (method_list);
66 method_list = method_list->method_next;
71 /* This routine is given a list of methods and records each of the
72 methods in the record table. This is the routine that does the
73 actual recording work.
75 The name and type pointers in the method list must be permanent and
76 immutable. */
77 void
78 __objc_register_selectors_from_list (struct objc_method_list *method_list)
80 int i = 0;
82 objc_mutex_lock (__objc_runtime_mutex);
83 while (i < method_list->method_count)
85 Method method = &method_list->method_list[i];
86 if (method->method_name)
88 method->method_name
89 = __sel_register_typed_name ((const char *) method->method_name,
90 method->method_types, 0, YES);
92 i += 1;
94 objc_mutex_unlock (__objc_runtime_mutex);
97 /* The same as __objc_register_selectors_from_list, but works on a
98 struct objc_method_description_list* instead of a struct
99 objc_method_list*. This is only used for protocols, which have
100 lists of method descriptions, not methods. */
101 void
102 __objc_register_selectors_from_description_list
103 (struct objc_method_description_list *method_list)
105 int i = 0;
107 objc_mutex_lock (__objc_runtime_mutex);
108 while (i < method_list->count)
110 struct objc_method_description *method = &method_list->list[i];
111 if (method->name)
113 method->name
114 = __sel_register_typed_name ((const char *) method->name,
115 method->types, 0, YES);
117 i += 1;
119 objc_mutex_unlock (__objc_runtime_mutex);
122 /* Register instance methods as class methods for root classes. */
123 void __objc_register_instance_methods_to_class (Class class)
125 struct objc_method_list *method_list;
126 struct objc_method_list *class_method_list;
127 int max_methods_no = 16;
128 struct objc_method_list *new_list;
129 Method curr_method;
131 /* Only if a root class. */
132 if (class->super_class)
133 return;
135 /* Allocate a method list to hold the new class methods. */
136 new_list = objc_calloc (sizeof (struct objc_method_list)
137 + sizeof (struct objc_method[max_methods_no]), 1);
138 method_list = class->methods;
139 class_method_list = class->class_pointer->methods;
140 curr_method = &new_list->method_list[0];
142 /* Iterate through the method lists for the class. */
143 while (method_list)
145 int i;
147 /* Iterate through the methods from this method list. */
148 for (i = 0; i < method_list->method_count; i++)
150 Method mth = &method_list->method_list[i];
151 if (mth->method_name
152 && ! search_for_method_in_list (class_method_list,
153 mth->method_name))
155 /* This instance method isn't a class method. Add it
156 into the new_list. */
157 *curr_method = *mth;
159 /* Reallocate the method list if necessary. */
160 if (++new_list->method_count == max_methods_no)
161 new_list =
162 objc_realloc (new_list, sizeof (struct objc_method_list)
163 + sizeof (struct
164 objc_method[max_methods_no += 16]));
165 curr_method = &new_list->method_list[new_list->method_count];
169 method_list = method_list->method_next;
172 /* If we created any new class methods then attach the method list
173 to the class. */
174 if (new_list->method_count)
176 new_list =
177 objc_realloc (new_list, sizeof (struct objc_method_list)
178 + sizeof (struct objc_method[new_list->method_count]));
179 new_list->method_next = class->class_pointer->methods;
180 class->class_pointer->methods = new_list;
182 else
183 objc_free(new_list);
185 __objc_update_dispatch_table_for_class (class->class_pointer);
188 BOOL
189 sel_isEqual (SEL s1, SEL s2)
191 if (s1 == 0 || s2 == 0)
192 return s1 == s2;
193 else
194 return s1->sel_id == s2->sel_id;
197 /* Return YES iff t1 and t2 have same method types. Ignore the
198 argframe layout. */
199 BOOL
200 sel_types_match (const char *t1, const char *t2)
202 if (! t1 || ! t2)
203 return NO;
204 while (*t1 && *t2)
206 if (*t1 == '+') t1++;
207 if (*t2 == '+') t2++;
208 while (isdigit ((unsigned char) *t1)) t1++;
209 while (isdigit ((unsigned char) *t2)) t2++;
210 /* xxx Remove these next two lines when qualifiers are put in
211 all selectors, not just Protocol selectors. */
212 t1 = objc_skip_type_qualifiers (t1);
213 t2 = objc_skip_type_qualifiers (t2);
214 if (! *t1 && ! *t2)
215 return YES;
216 if (*t1 != *t2)
217 return NO;
218 t1++;
219 t2++;
221 return NO;
224 /* Return selector representing name. */
226 sel_get_typed_uid (const char *name, const char *types)
228 struct objc_list *l;
229 sidx i;
231 objc_mutex_lock (__objc_runtime_mutex);
233 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
234 if (i == 0)
236 objc_mutex_unlock (__objc_runtime_mutex);
237 return 0;
240 for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
241 l; l = l->tail)
243 SEL s = (SEL) l->head;
244 if (types == 0 || s->sel_types == 0)
246 if (s->sel_types == types)
248 objc_mutex_unlock (__objc_runtime_mutex);
249 return s;
252 else if (sel_types_match (s->sel_types, types))
254 objc_mutex_unlock (__objc_runtime_mutex);
255 return s;
259 objc_mutex_unlock (__objc_runtime_mutex);
260 return 0;
263 /* Return selector representing name; prefer a selector with non-NULL
264 type. */
266 sel_get_any_typed_uid (const char *name)
268 struct objc_list *l;
269 sidx i;
270 SEL s = NULL;
272 objc_mutex_lock (__objc_runtime_mutex);
274 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
275 if (i == 0)
277 objc_mutex_unlock (__objc_runtime_mutex);
278 return 0;
281 for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
282 l; l = l->tail)
284 s = (SEL) l->head;
285 if (s->sel_types)
287 objc_mutex_unlock (__objc_runtime_mutex);
288 return s;
292 objc_mutex_unlock (__objc_runtime_mutex);
293 return s;
296 /* Return selector representing name. */
298 sel_get_any_uid (const char *name)
300 struct objc_list *l;
301 sidx i;
303 objc_mutex_lock (__objc_runtime_mutex);
305 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
306 if (soffset_decode (i) == 0)
308 objc_mutex_unlock (__objc_runtime_mutex);
309 return 0;
312 l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
313 objc_mutex_unlock (__objc_runtime_mutex);
315 if (l == 0)
316 return 0;
318 return (SEL) l->head;
321 /* Get the name of a selector. If the selector is unknown, the empty
322 string "" is returned. */
323 const char *sel_getName (SEL selector)
325 const char *ret;
327 if (selector == NULL)
328 return "<null selector>";
330 objc_mutex_lock (__objc_runtime_mutex);
331 if ((soffset_decode ((sidx)selector->sel_id) > 0)
332 && (soffset_decode ((sidx)selector->sel_id) <= __objc_selector_max_index))
333 ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id);
334 else
335 ret = 0;
336 objc_mutex_unlock (__objc_runtime_mutex);
337 return ret;
340 /* Traditional GNU Objective-C Runtime API. */
341 const char *sel_get_name (SEL selector)
343 if (selector == NULL)
344 return 0;
346 return sel_getName (selector);
349 BOOL
350 sel_is_mapped (SEL selector)
352 unsigned int idx = soffset_decode ((sidx)selector->sel_id);
353 return ((idx > 0) && (idx <= __objc_selector_max_index));
356 const char *sel_getType (SEL selector)
358 if (selector)
359 return selector->sel_types;
360 else
361 return 0;
364 /* Traditional GNU Objective-C Runtime API. */
365 const char *sel_get_type (SEL selector)
367 return sel_getType (selector);
370 /* The uninstalled dispatch table. */
371 extern struct sarray *__objc_uninstalled_dtable;
373 /* __sel_register_typed_name allocates lots of struct objc_selector:s
374 of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the
375 number of malloc calls and memory lost to malloc overhead, we
376 allocate objc_selector:s in blocks here. This is only called from
377 __sel_register_typed_name, and __sel_register_typed_name may only
378 be called when __objc_runtime_mutex is locked.
380 Note that the objc_selector:s allocated from
381 __sel_register_typed_name are never freed.
383 62 because 62 * sizeof (struct objc_selector) = 496 (992). This
384 should let malloc add some overhead and use a nice, round 512
385 (1024) byte chunk. */
386 #define SELECTOR_POOL_SIZE 62
387 static struct objc_selector *selector_pool;
388 static int selector_pool_left;
390 static struct objc_selector *
391 pool_alloc_selector(void)
393 if (!selector_pool_left)
395 selector_pool = objc_malloc (sizeof (struct objc_selector)
396 * SELECTOR_POOL_SIZE);
397 selector_pool_left = SELECTOR_POOL_SIZE;
399 return &selector_pool[--selector_pool_left];
402 /* Store the passed selector name in the selector record and return
403 its selector value (value returned by sel_get_uid). Assume that
404 the calling function has locked down __objc_runtime_mutex. The
405 is_const parameter tells us if the name and types parameters are
406 really constant or not. If YES then they are constant and we can
407 just store the pointers. If NO then we need to copy name and types
408 because the pointers may disappear later on. */
410 __sel_register_typed_name (const char *name, const char *types,
411 struct objc_selector *orig, BOOL is_const)
413 struct objc_selector *j;
414 sidx i;
415 struct objc_list *l;
417 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
418 if (soffset_decode (i) != 0)
420 for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
421 l; l = l->tail)
423 SEL s = (SEL) l->head;
424 if (types == 0 || s->sel_types == 0)
426 if (s->sel_types == types)
428 if (orig)
430 orig->sel_id = (void *) i;
431 return orig;
433 else
434 return s;
437 else if (! strcmp (s->sel_types, types))
439 if (orig)
441 orig->sel_id = (void *) i;
442 return orig;
444 else
445 return s;
448 if (orig)
449 j = orig;
450 else
451 j = pool_alloc_selector ();
453 j->sel_id = (void *) i;
454 /* Can we use the pointer or must copy types? Don't copy if
455 NULL. */
456 if ((is_const) || (types == 0))
457 j->sel_types = (const char *) types;
458 else
460 j->sel_types = (char *) objc_malloc (strlen (types) + 1);
461 strcpy ((char *) j->sel_types, types);
463 l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
465 else
467 __objc_selector_max_index += 1;
468 i = soffset_encode (__objc_selector_max_index);
469 if (orig)
470 j = orig;
471 else
472 j = pool_alloc_selector ();
474 j->sel_id = (void *) i;
475 /* Can we use the pointer or must copy types? Don't copy if
476 NULL. */
477 if ((is_const) || (types == 0))
478 j->sel_types = (const char *) types;
479 else
481 j->sel_types = (char *) objc_malloc (strlen (types) + 1);
482 strcpy ((char *) j->sel_types, types);
484 l = 0;
487 DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types,
488 (long) soffset_decode (i));
491 int is_new = (l == 0);
492 const char *new_name;
494 /* Can we use the pointer or must copy name? Don't copy if
495 NULL. */
496 if ((is_const) || (name == 0))
497 new_name = name;
498 else
500 new_name = (char *) objc_malloc (strlen (name) + 1);
501 strcpy ((char *) new_name, name);
504 l = list_cons ((void *) j, l);
505 sarray_at_put_safe (__objc_selector_names, i, (void *) new_name);
506 sarray_at_put_safe (__objc_selector_array, i, (void *) l);
507 if (is_new)
508 objc_hash_add (&__objc_selector_hash, (void *) new_name, (void *) i);
511 sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
513 return (SEL) j;
517 sel_registerName (const char *name)
519 SEL ret;
521 objc_mutex_lock (__objc_runtime_mutex);
522 /* Assume that name is not constant static memory and needs to be
523 copied before put into a runtime structure. is_const == NO. */
524 ret = __sel_register_typed_name (name, 0, 0, NO);
525 objc_mutex_unlock (__objc_runtime_mutex);
527 return ret;
530 /* Traditional GNU Objective-C Runtime API. */
532 sel_register_name (const char *name)
534 return sel_registerName (name);
538 sel_registerTypedName (const char *name, const char *type)
540 SEL ret;
542 objc_mutex_lock (__objc_runtime_mutex);
543 /* Assume that name and type are not constant static memory and need
544 to be copied before put into a runtime structure. is_const ==
545 NO. */
546 ret = __sel_register_typed_name (name, type, 0, NO);
547 objc_mutex_unlock (__objc_runtime_mutex);
549 return ret;
553 sel_register_typed_name (const char *name, const char *type)
555 return sel_registerTypedName (name, type);
558 /* Return the selector representing name. */
560 sel_getUid (const char *name)
562 return sel_registerTypedName (name, 0);
565 /* Traditional GNU Objective-C Runtime API. */
567 sel_get_uid (const char *name)
569 return sel_getUid (name);