In libobjc/: 2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com>
[official-gcc.git] / libobjc / selector.c
blob699e52ee966ea48fbb0a0237de0c068a8295bf4a
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"
33 #include "objc-private/selector.h"
35 /* Initial selector hash table size. Value doesn't matter much. */
36 #define SELECTOR_HASH_SIZE 128
38 /* Tables mapping selector names to uid and opposite. */
39 static struct sarray *__objc_selector_array = 0; /* uid -> sel !T:MUTEX */
40 static struct sarray *__objc_selector_names = 0; /* uid -> name !T:MUTEX */
41 static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */
43 /* Number of selectors stored in each of the above tables. */
44 unsigned int __objc_selector_max_index = 0; /* !T:MUTEX */
46 /* Forward-declare an internal function. */
47 static SEL
48 __sel_register_typed_name (const char *name, const char *types,
49 struct objc_selector *orig, BOOL is_const);
51 void __objc_init_selector_tables (void)
53 __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0);
54 __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0);
55 __objc_selector_hash
56 = objc_hash_new (SELECTOR_HASH_SIZE,
57 (hash_func_type) objc_hash_string,
58 (compare_func_type) objc_compare_strings);
61 /* Register a bunch of selectors from the table of selectors in a
62 module. 'selectors' should not be NULL. The list is terminated by
63 a selectors with a NULL sel_id. The selectors are assumed to
64 contain the 'name' in the sel_id field; this is replaced with the
65 final selector id after they are registered. */
66 void
67 __objc_register_selectors_from_module (struct objc_selector *selectors)
69 int i;
71 for (i = 0; selectors[i].sel_id; ++i)
73 const char *name, *type;
74 name = (char *) selectors[i].sel_id;
75 type = (char *) selectors[i].sel_types;
76 /* Constructors are constant static data and we can safely store
77 pointers to them in the runtime structures, so we set
78 is_const == YES. */
79 __sel_register_typed_name (name, type, (struct objc_selector *) &(selectors[i]),
80 /* is_const */ YES);
84 /* This routine is given a class and records all of the methods in its
85 class structure in the record table. */
86 void
87 __objc_register_selectors_from_class (Class class)
89 struct objc_method_list * method_list;
91 method_list = class->methods;
92 while (method_list)
94 __objc_register_selectors_from_list (method_list);
95 method_list = method_list->method_next;
100 /* This routine is given a list of methods and records each of the
101 methods in the record table. This is the routine that does the
102 actual recording work.
104 The name and type pointers in the method list must be permanent and
105 immutable. */
106 void
107 __objc_register_selectors_from_list (struct objc_method_list *method_list)
109 int i = 0;
111 objc_mutex_lock (__objc_runtime_mutex);
112 while (i < method_list->method_count)
114 Method method = &method_list->method_list[i];
115 if (method->method_name)
117 method->method_name
118 = __sel_register_typed_name ((const char *) method->method_name,
119 method->method_types, 0, YES);
121 i += 1;
123 objc_mutex_unlock (__objc_runtime_mutex);
126 /* The same as __objc_register_selectors_from_list, but works on a
127 struct objc_method_description_list* instead of a struct
128 objc_method_list*. This is only used for protocols, which have
129 lists of method descriptions, not methods. */
130 void
131 __objc_register_selectors_from_description_list
132 (struct objc_method_description_list *method_list)
134 int i = 0;
136 objc_mutex_lock (__objc_runtime_mutex);
137 while (i < method_list->count)
139 struct objc_method_description *method = &method_list->list[i];
140 if (method->name)
142 method->name
143 = __sel_register_typed_name ((const char *) method->name,
144 method->types, 0, YES);
146 i += 1;
148 objc_mutex_unlock (__objc_runtime_mutex);
151 /* Register instance methods as class methods for root classes. */
152 void __objc_register_instance_methods_to_class (Class class)
154 struct objc_method_list *method_list;
155 struct objc_method_list *class_method_list;
156 int max_methods_no = 16;
157 struct objc_method_list *new_list;
158 Method curr_method;
160 /* Only if a root class. */
161 if (class->super_class)
162 return;
164 /* Allocate a method list to hold the new class methods. */
165 new_list = objc_calloc (sizeof (struct objc_method_list)
166 + sizeof (struct objc_method[max_methods_no]), 1);
167 method_list = class->methods;
168 class_method_list = class->class_pointer->methods;
169 curr_method = &new_list->method_list[0];
171 /* Iterate through the method lists for the class. */
172 while (method_list)
174 int i;
176 /* Iterate through the methods from this method list. */
177 for (i = 0; i < method_list->method_count; i++)
179 Method mth = &method_list->method_list[i];
180 if (mth->method_name
181 && ! search_for_method_in_list (class_method_list,
182 mth->method_name))
184 /* This instance method isn't a class method. Add it
185 into the new_list. */
186 *curr_method = *mth;
188 /* Reallocate the method list if necessary. */
189 if (++new_list->method_count == max_methods_no)
190 new_list =
191 objc_realloc (new_list, sizeof (struct objc_method_list)
192 + sizeof (struct
193 objc_method[max_methods_no += 16]));
194 curr_method = &new_list->method_list[new_list->method_count];
198 method_list = method_list->method_next;
201 /* If we created any new class methods then attach the method list
202 to the class. */
203 if (new_list->method_count)
205 new_list =
206 objc_realloc (new_list, sizeof (struct objc_method_list)
207 + sizeof (struct objc_method[new_list->method_count]));
208 new_list->method_next = class->class_pointer->methods;
209 class->class_pointer->methods = new_list;
211 else
212 objc_free(new_list);
214 __objc_update_dispatch_table_for_class (class->class_pointer);
217 BOOL
218 sel_isEqual (SEL s1, SEL s2)
220 if (s1 == 0 || s2 == 0)
221 return s1 == s2;
222 else
223 return s1->sel_id == s2->sel_id;
226 /* Return YES iff t1 and t2 have same method types. Ignore the
227 argframe layout. */
228 BOOL
229 sel_types_match (const char *t1, const char *t2)
231 if (! t1 || ! t2)
232 return NO;
233 while (*t1 && *t2)
235 if (*t1 == '+') t1++;
236 if (*t2 == '+') t2++;
237 while (isdigit ((unsigned char) *t1)) t1++;
238 while (isdigit ((unsigned char) *t2)) t2++;
239 /* xxx Remove these next two lines when qualifiers are put in
240 all selectors, not just Protocol selectors. */
241 t1 = objc_skip_type_qualifiers (t1);
242 t2 = objc_skip_type_qualifiers (t2);
243 if (! *t1 && ! *t2)
244 return YES;
245 if (*t1 != *t2)
246 return NO;
247 t1++;
248 t2++;
250 return NO;
253 /* Return selector representing name. */
255 sel_get_typed_uid (const char *name, const char *types)
257 struct objc_list *l;
258 sidx i;
260 objc_mutex_lock (__objc_runtime_mutex);
262 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
263 if (i == 0)
265 objc_mutex_unlock (__objc_runtime_mutex);
266 return 0;
269 for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
270 l; l = l->tail)
272 SEL s = (SEL) l->head;
273 if (types == 0 || s->sel_types == 0)
275 if (s->sel_types == types)
277 objc_mutex_unlock (__objc_runtime_mutex);
278 return s;
281 else if (sel_types_match (s->sel_types, types))
283 objc_mutex_unlock (__objc_runtime_mutex);
284 return s;
288 objc_mutex_unlock (__objc_runtime_mutex);
289 return 0;
292 /* Return selector representing name; prefer a selector with non-NULL
293 type. */
295 sel_get_any_typed_uid (const char *name)
297 struct objc_list *l;
298 sidx i;
299 SEL s = NULL;
301 objc_mutex_lock (__objc_runtime_mutex);
303 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
304 if (i == 0)
306 objc_mutex_unlock (__objc_runtime_mutex);
307 return 0;
310 for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
311 l; l = l->tail)
313 s = (SEL) l->head;
314 if (s->sel_types)
316 objc_mutex_unlock (__objc_runtime_mutex);
317 return s;
321 objc_mutex_unlock (__objc_runtime_mutex);
322 return s;
325 /* Return selector representing name. */
327 sel_get_any_uid (const char *name)
329 struct objc_list *l;
330 sidx i;
332 objc_mutex_lock (__objc_runtime_mutex);
334 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
335 if (soffset_decode (i) == 0)
337 objc_mutex_unlock (__objc_runtime_mutex);
338 return 0;
341 l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
342 objc_mutex_unlock (__objc_runtime_mutex);
344 if (l == 0)
345 return 0;
347 return (SEL) l->head;
350 /* Get the name of a selector. If the selector is unknown, the empty
351 string "" is returned. */
352 const char *sel_getName (SEL selector)
354 const char *ret;
356 if (selector == NULL)
357 return "<null selector>";
359 objc_mutex_lock (__objc_runtime_mutex);
360 if ((soffset_decode ((sidx)selector->sel_id) > 0)
361 && (soffset_decode ((sidx)selector->sel_id) <= __objc_selector_max_index))
362 ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id);
363 else
364 ret = 0;
365 objc_mutex_unlock (__objc_runtime_mutex);
366 return ret;
369 /* Traditional GNU Objective-C Runtime API. */
370 const char *sel_get_name (SEL selector)
372 if (selector == NULL)
373 return 0;
375 return sel_getName (selector);
378 BOOL
379 sel_is_mapped (SEL selector)
381 unsigned int idx = soffset_decode ((sidx)selector->sel_id);
382 return ((idx > 0) && (idx <= __objc_selector_max_index));
385 const char *sel_getType (SEL selector)
387 if (selector)
388 return selector->sel_types;
389 else
390 return 0;
393 /* Traditional GNU Objective-C Runtime API. */
394 const char *sel_get_type (SEL selector)
396 return sel_getType (selector);
399 /* The uninstalled dispatch table. */
400 extern struct sarray *__objc_uninstalled_dtable;
402 /* __sel_register_typed_name allocates lots of struct objc_selector:s
403 of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the
404 number of malloc calls and memory lost to malloc overhead, we
405 allocate objc_selector:s in blocks here. This is only called from
406 __sel_register_typed_name, and __sel_register_typed_name may only
407 be called when __objc_runtime_mutex is locked.
409 Note that the objc_selector:s allocated from
410 __sel_register_typed_name are never freed.
412 62 because 62 * sizeof (struct objc_selector) = 496 (992). This
413 should let malloc add some overhead and use a nice, round 512
414 (1024) byte chunk. */
415 #define SELECTOR_POOL_SIZE 62
416 static struct objc_selector *selector_pool;
417 static int selector_pool_left;
419 static struct objc_selector *
420 pool_alloc_selector(void)
422 if (!selector_pool_left)
424 selector_pool = objc_malloc (sizeof (struct objc_selector)
425 * SELECTOR_POOL_SIZE);
426 selector_pool_left = SELECTOR_POOL_SIZE;
428 return &selector_pool[--selector_pool_left];
431 /* Store the passed selector name in the selector record and return
432 its selector value (value returned by sel_get_uid). Assume that
433 the calling function has locked down __objc_runtime_mutex. The
434 'is_const' parameter tells us if the name and types parameters are
435 really constant or not. If YES then they are constant and we can
436 just store the pointers. If NO then we need to copy name and types
437 because the pointers may disappear later on. If the 'orig'
438 parameter is not NULL, then we are registering a selector from a
439 module, and 'orig' is that selector. In this case, we can put the
440 selector in the tables if needed, and orig->sel_id is updated with
441 the selector ID of the registered selector, and 'orig' is
442 returned. */
443 static SEL
444 __sel_register_typed_name (const char *name, const char *types,
445 struct objc_selector *orig, BOOL is_const)
447 struct objc_selector *j;
448 sidx i;
449 struct objc_list *l;
451 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
452 if (soffset_decode (i) != 0)
454 for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
455 l; l = l->tail)
457 SEL s = (SEL) l->head;
458 if (types == 0 || s->sel_types == 0)
460 if (s->sel_types == types)
462 if (orig)
464 orig->sel_id = (void *) i;
465 return orig;
467 else
468 return s;
471 else if (! strcmp (s->sel_types, types))
473 if (orig)
475 orig->sel_id = (void *) i;
476 return orig;
478 else
479 return s;
482 if (orig)
483 j = orig;
484 else
485 j = pool_alloc_selector ();
487 j->sel_id = (void *) i;
488 /* Can we use the pointer or must copy types? Don't copy if
489 NULL. */
490 if ((is_const) || (types == 0))
491 j->sel_types = (const char *) types;
492 else
494 j->sel_types = (char *) objc_malloc (strlen (types) + 1);
495 strcpy ((char *) j->sel_types, types);
497 l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
499 else
501 __objc_selector_max_index += 1;
502 i = soffset_encode (__objc_selector_max_index);
503 if (orig)
504 j = orig;
505 else
506 j = pool_alloc_selector ();
508 j->sel_id = (void *) i;
509 /* Can we use the pointer or must copy types? Don't copy if
510 NULL. */
511 if ((is_const) || (types == 0))
512 j->sel_types = (const char *) types;
513 else
515 j->sel_types = (char *) objc_malloc (strlen (types) + 1);
516 strcpy ((char *) j->sel_types, types);
518 l = 0;
521 DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types,
522 (long) soffset_decode (i));
525 int is_new = (l == 0);
526 const char *new_name;
528 /* Can we use the pointer or must copy name? Don't copy if
529 NULL. */
530 if ((is_const) || (name == 0))
531 new_name = name;
532 else
534 new_name = (char *) objc_malloc (strlen (name) + 1);
535 strcpy ((char *) new_name, name);
538 l = list_cons ((void *) j, l);
539 sarray_at_put_safe (__objc_selector_names, i, (void *) new_name);
540 sarray_at_put_safe (__objc_selector_array, i, (void *) l);
541 if (is_new)
542 objc_hash_add (&__objc_selector_hash, (void *) new_name, (void *) i);
545 sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
547 return (SEL) j;
551 sel_registerName (const char *name)
553 SEL ret;
555 objc_mutex_lock (__objc_runtime_mutex);
556 /* Assume that name is not constant static memory and needs to be
557 copied before put into a runtime structure. is_const == NO. */
558 ret = __sel_register_typed_name (name, 0, 0, NO);
559 objc_mutex_unlock (__objc_runtime_mutex);
561 return ret;
564 /* Traditional GNU Objective-C Runtime API. */
566 sel_register_name (const char *name)
568 return sel_registerName (name);
572 sel_registerTypedName (const char *name, const char *type)
574 SEL ret;
576 objc_mutex_lock (__objc_runtime_mutex);
577 /* Assume that name and type are not constant static memory and need
578 to be copied before put into a runtime structure. is_const ==
579 NO. */
580 ret = __sel_register_typed_name (name, type, 0, NO);
581 objc_mutex_unlock (__objc_runtime_mutex);
583 return ret;
587 sel_register_typed_name (const char *name, const char *type)
589 return sel_registerTypedName (name, type);
592 /* Return the selector representing name. */
594 sel_getUid (const char *name)
596 return sel_registerTypedName (name, 0);
599 /* Traditional GNU Objective-C Runtime API. */
601 sel_get_uid (const char *name)
603 return sel_getUid (name);