1 /* GNU Objective C Runtime selector related functions
2 Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Kresten Krab Thorup
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 3, or (at your option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
26 #include "objc-private/common.h"
27 #include "objc/runtime.h"
29 #include "objc-private/hash.h"
30 #include "objc-private/objc-list.h"
31 #include "objc-private/module-abi-8.h"
32 #include "objc-private/runtime.h"
33 #include "objc-private/sarray.h"
34 #include "objc-private/selector.h"
35 #include <stdlib.h> /* For malloc. */
37 /* Initial selector hash table size. Value doesn't matter much. */
38 #define SELECTOR_HASH_SIZE 128
40 /* Tables mapping selector names to uid and opposite. */
41 static struct sarray
*__objc_selector_array
= 0; /* uid -> sel !T:MUTEX */
42 static struct sarray
*__objc_selector_names
= 0; /* uid -> name !T:MUTEX */
43 static cache_ptr __objc_selector_hash
= 0; /* name -> uid !T:MUTEX */
45 /* Number of selectors stored in each of the above tables. */
46 unsigned int __objc_selector_max_index
= 0; /* !T:MUTEX */
48 /* Forward-declare an internal function. */
50 __sel_register_typed_name (const char *name
, const char *types
,
51 struct objc_selector
*orig
, BOOL is_const
);
53 void __objc_init_selector_tables (void)
55 __objc_selector_array
= sarray_new (SELECTOR_HASH_SIZE
, 0);
56 __objc_selector_names
= sarray_new (SELECTOR_HASH_SIZE
, 0);
58 = objc_hash_new (SELECTOR_HASH_SIZE
,
59 (hash_func_type
) objc_hash_string
,
60 (compare_func_type
) objc_compare_strings
);
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. */
69 __objc_register_selectors_from_module (struct objc_selector
*selectors
)
73 for (i
= 0; selectors
[i
].sel_id
; ++i
)
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
81 __sel_register_typed_name (name
, type
, (struct objc_selector
*) &(selectors
[i
]),
86 /* This routine is given a class and records all of the methods in its
87 class structure in the record table. */
89 __objc_register_selectors_from_class (Class
class)
91 struct objc_method_list
* method_list
;
93 method_list
= class->methods
;
96 __objc_register_selectors_from_list (method_list
);
97 method_list
= method_list
->method_next
;
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.
106 The name and type pointers in the method list must be permanent and
109 __objc_register_selectors_from_list (struct objc_method_list
*method_list
)
113 objc_mutex_lock (__objc_runtime_mutex
);
114 while (i
< method_list
->method_count
)
116 Method method
= &method_list
->method_list
[i
];
117 if (method
->method_name
)
120 = __sel_register_typed_name ((const char *) method
->method_name
,
121 method
->method_types
, 0, YES
);
125 objc_mutex_unlock (__objc_runtime_mutex
);
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
131 lists of method descriptions, not methods. */
133 __objc_register_selectors_from_description_list
134 (struct objc_method_description_list
*method_list
)
138 objc_mutex_lock (__objc_runtime_mutex
);
139 while (i
< method_list
->count
)
141 struct objc_method_description
*method
= &method_list
->list
[i
];
145 = __sel_register_typed_name ((const char *) method
->name
,
146 method
->types
, 0, YES
);
150 objc_mutex_unlock (__objc_runtime_mutex
);
153 /* Register instance methods as class methods for root classes. */
154 void __objc_register_instance_methods_to_class (Class
class)
156 struct objc_method_list
*method_list
;
157 struct objc_method_list
*class_method_list
;
158 int max_methods_no
= 16;
159 struct objc_method_list
*new_list
;
162 /* Only if a root class. */
163 if (class->super_class
)
166 /* Allocate a method list to hold the new class methods. */
167 new_list
= objc_calloc (sizeof (struct objc_method_list
)
168 + sizeof (struct objc_method
[max_methods_no
]), 1);
169 method_list
= class->methods
;
170 class_method_list
= class->class_pointer
->methods
;
171 curr_method
= &new_list
->method_list
[0];
173 /* Iterate through the method lists for the class. */
178 /* Iterate through the methods from this method list. */
179 for (i
= 0; i
< method_list
->method_count
; i
++)
181 Method mth
= &method_list
->method_list
[i
];
183 && ! search_for_method_in_list (class_method_list
,
186 /* This instance method isn't a class method. Add it
187 into the new_list. */
190 /* Reallocate the method list if necessary. */
191 if (++new_list
->method_count
== max_methods_no
)
193 objc_realloc (new_list
, sizeof (struct objc_method_list
)
195 objc_method
[max_methods_no
+= 16]));
196 curr_method
= &new_list
->method_list
[new_list
->method_count
];
200 method_list
= method_list
->method_next
;
203 /* If we created any new class methods then attach the method list
205 if (new_list
->method_count
)
208 objc_realloc (new_list
, sizeof (struct objc_method_list
)
209 + sizeof (struct objc_method
[new_list
->method_count
]));
210 new_list
->method_next
= class->class_pointer
->methods
;
211 class->class_pointer
->methods
= new_list
;
216 __objc_update_dispatch_table_for_class (class->class_pointer
);
220 sel_isEqual (SEL s1
, SEL s2
)
222 if (s1
== 0 || s2
== 0)
225 return s1
->sel_id
== s2
->sel_id
;
228 /* Return YES iff t1 and t2 have same method types. Ignore the
231 sel_types_match (const char *t1
, const char *t2
)
237 if (*t1
== '+') t1
++;
238 if (*t2
== '+') t2
++;
239 while (isdigit ((unsigned char) *t1
)) t1
++;
240 while (isdigit ((unsigned char) *t2
)) t2
++;
241 /* xxx Remove these next two lines when qualifiers are put in
242 all selectors, not just Protocol selectors. */
243 t1
= objc_skip_type_qualifiers (t1
);
244 t2
= objc_skip_type_qualifiers (t2
);
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()). */
261 sel_get_typed_uid (const char *name
, const char *types
)
266 objc_mutex_lock (__objc_runtime_mutex
);
268 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
271 objc_mutex_unlock (__objc_runtime_mutex
);
275 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
278 SEL s
= (SEL
) l
->head
;
279 if (types
== 0 || s
->sel_types
== 0)
281 if (s
->sel_types
== types
)
283 objc_mutex_unlock (__objc_runtime_mutex
);
287 else if (sel_types_match (s
->sel_types
, types
))
289 objc_mutex_unlock (__objc_runtime_mutex
);
294 objc_mutex_unlock (__objc_runtime_mutex
);
298 /* Return selector representing name; prefer a selector with non-NULL
299 type. In the Modern API, sel_getTypedSelector() is similar but
300 returns NULL if a typed selector couldn't be found. */
302 sel_get_any_typed_uid (const char *name
)
308 objc_mutex_lock (__objc_runtime_mutex
);
310 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
313 objc_mutex_unlock (__objc_runtime_mutex
);
317 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
323 objc_mutex_unlock (__objc_runtime_mutex
);
328 objc_mutex_unlock (__objc_runtime_mutex
);
332 /* Return selector representing name. */
334 sel_get_any_uid (const char *name
)
339 objc_mutex_lock (__objc_runtime_mutex
);
341 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
342 if (soffset_decode (i
) == 0)
344 objc_mutex_unlock (__objc_runtime_mutex
);
348 l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
349 objc_mutex_unlock (__objc_runtime_mutex
);
354 return (SEL
) l
->head
;
358 sel_getTypedSelector (const char *name
)
365 objc_mutex_lock (__objc_runtime_mutex
);
367 /* Look for a typed selector. */
368 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
372 SEL returnValue
= NULL
;
374 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
377 SEL s
= (SEL
) l
->head
;
380 if (returnValue
== NULL
)
382 /* First typed selector that we find. Keep it in
383 returnValue, but keep checking as we want to
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
)
396 else if (sel_types_match (returnValue
->sel_types
, s
->sel_types
))
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
);
409 if (returnValue
!= NULL
)
411 objc_mutex_unlock (__objc_runtime_mutex
);
416 /* No typed selector found. Return NULL. */
417 objc_mutex_unlock (__objc_runtime_mutex
);
422 sel_copyTypedSelectorList (const char *name
, unsigned int *numberOfReturnedSelectors
)
424 unsigned int count
= 0;
425 SEL
*returnValue
= NULL
;
430 if (numberOfReturnedSelectors
)
431 *numberOfReturnedSelectors
= 0;
435 objc_mutex_lock (__objc_runtime_mutex
);
437 /* Count how many selectors we have. */
438 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
441 struct objc_list
*selector_list
= NULL
;
442 selector_list
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
444 /* Count how many selectors we have. */
447 for (l
= selector_list
; l
; l
= l
->tail
)
453 /* Allocate enough memory to hold them. */
454 returnValue
= (SEL
*)(malloc (sizeof (SEL
) * (count
+ 1)));
456 /* Copy the selectors. */
459 for (j
= 0; j
< count
; j
++)
461 returnValue
[j
] = (SEL
)(selector_list
->head
);
462 selector_list
= selector_list
->tail
;
464 returnValue
[j
] = NULL
;
469 objc_mutex_unlock (__objc_runtime_mutex
);
471 if (numberOfReturnedSelectors
)
472 *numberOfReturnedSelectors
= count
;
477 /* Get the name of a selector. If the selector is unknown, the empty
478 string "" is returned. */
479 const char *sel_getName (SEL selector
)
483 if (selector
== NULL
)
484 return "<null selector>";
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
))
489 ret
= sarray_get_safe (__objc_selector_names
, (sidx
) selector
->sel_id
);
492 objc_mutex_unlock (__objc_runtime_mutex
);
496 /* Traditional GNU Objective-C Runtime API. */
497 const char *sel_get_name (SEL selector
)
499 if (selector
== NULL
)
502 return sel_getName (selector
);
506 sel_is_mapped (SEL selector
)
508 unsigned int idx
= soffset_decode ((sidx
)selector
->sel_id
);
509 return ((idx
> 0) && (idx
<= __objc_selector_max_index
));
512 const char *sel_getTypeEncoding (SEL selector
)
515 return selector
->sel_types
;
520 /* Traditional GNU Objective-C Runtime API. */
521 const char *sel_get_type (SEL selector
)
523 return sel_getTypeEncoding (selector
);
526 /* The uninstalled dispatch table. */
527 extern struct sarray
*__objc_uninstalled_dtable
;
529 /* __sel_register_typed_name allocates lots of struct objc_selector:s
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.
536 Note that the objc_selector:s allocated from
537 __sel_register_typed_name are never freed.
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. */
542 #define SELECTOR_POOL_SIZE 62
543 static struct objc_selector
*selector_pool
;
544 static int selector_pool_left
;
546 static struct objc_selector
*
547 pool_alloc_selector(void)
549 if (!selector_pool_left
)
551 selector_pool
= objc_malloc (sizeof (struct objc_selector
)
552 * SELECTOR_POOL_SIZE
);
553 selector_pool_left
= SELECTOR_POOL_SIZE
;
555 return &selector_pool
[--selector_pool_left
];
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
561 'is_const' parameter tells us if the name and types parameters are
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
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
571 __sel_register_typed_name (const char *name
, const char *types
,
572 struct objc_selector
*orig
, BOOL is_const
)
574 struct objc_selector
*j
;
578 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
579 if (soffset_decode (i
) != 0)
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
);
586 SEL s
= (SEL
)l
->head
;
587 if (types
== 0 || s
->sel_types
== 0)
589 if (s
->sel_types
== types
)
593 orig
->sel_id
= (void *)i
;
600 else if (! strcmp (s
->sel_types
, types
))
604 orig
->sel_id
= (void *)i
;
611 /* A selector with this specific name/type combination does not
612 exist yet. We need to register it. */
616 j
= pool_alloc_selector ();
618 j
->sel_id
= (void *)i
;
619 /* Can we use the pointer or must we copy types ? Don't copy if
621 if ((is_const
) || (types
== 0))
622 j
->sel_types
= types
;
625 j
->sel_types
= (char *)objc_malloc (strlen (types
) + 1);
626 strcpy ((char *)j
->sel_types
, types
);
628 l
= (struct objc_list
*)sarray_get_safe (__objc_selector_array
, i
);
632 /* There are no other selectors with this name registered in the
634 const char *new_name
;
637 __objc_selector_max_index
+= 1;
638 i
= soffset_encode (__objc_selector_max_index
);
640 /* Prepare the selector. */
644 j
= pool_alloc_selector ();
646 j
->sel_id
= (void *)i
;
647 /* Can we use the pointer or must we copy types ? Don't copy if
649 if (is_const
|| (types
== 0))
650 j
->sel_types
= types
;
653 j
->sel_types
= (char *)objc_malloc (strlen (types
) + 1);
654 strcpy ((char *)j
->sel_types
, types
);
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. */
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))
668 new_name
= (char *)objc_malloc (strlen (name
) + 1);
669 strcpy ((char *)new_name
, name
);
672 /* This maps the sel_id to the name. */
673 sarray_at_put_safe (__objc_selector_names
, i
, (void *)new_name
);
675 /* This maps the name to the sel_id. */
676 objc_hash_add (&__objc_selector_hash
, (void *)new_name
, (void *)i
);
681 DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name
, types
,
682 (long)soffset_decode (i
));
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
);
688 sarray_realloc (__objc_uninstalled_dtable
, __objc_selector_max_index
+ 1);
694 sel_registerName (const char *name
)
701 objc_mutex_lock (__objc_runtime_mutex
);
702 /* Assume that name is not constant static memory and needs to be
703 copied before put into a runtime structure. is_const == NO. */
704 ret
= __sel_register_typed_name (name
, 0, 0, NO
);
705 objc_mutex_unlock (__objc_runtime_mutex
);
710 /* Traditional GNU Objective-C Runtime API. */
712 sel_register_name (const char *name
)
714 return sel_registerName (name
);
718 sel_registerTypedName (const char *name
, const char *type
)
725 objc_mutex_lock (__objc_runtime_mutex
);
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 ==
729 ret
= __sel_register_typed_name (name
, type
, 0, NO
);
730 objc_mutex_unlock (__objc_runtime_mutex
);
736 sel_register_typed_name (const char *name
, const char *type
)
738 return sel_registerTypedName (name
, type
);
741 /* Return the selector representing name. */
743 sel_getUid (const char *name
)
745 return sel_registerTypedName (name
, 0);
748 /* Traditional GNU Objective-C Runtime API. */
750 sel_get_uid (const char *name
)
752 return sel_getUid (name
);