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
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"
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 void __objc_init_selector_tables (void)
48 __objc_selector_array
= sarray_new (SELECTOR_HASH_SIZE
, 0);
49 __objc_selector_names
= sarray_new (SELECTOR_HASH_SIZE
, 0);
51 = objc_hash_new (SELECTOR_HASH_SIZE
,
52 (hash_func_type
) objc_hash_string
,
53 (compare_func_type
) objc_compare_strings
);
56 /* This routine is given a class and records all of the methods in its
57 class structure in the record table. */
59 __objc_register_selectors_from_class (Class
class)
61 struct objc_method_list
* method_list
;
63 method_list
= class->methods
;
66 __objc_register_selectors_from_list (method_list
);
67 method_list
= method_list
->method_next
;
72 /* This routine is given a list of methods and records each of the
73 methods in the record table. This is the routine that does the
74 actual recording work.
76 The name and type pointers in the method list must be permanent and
79 __objc_register_selectors_from_list (struct objc_method_list
*method_list
)
83 objc_mutex_lock (__objc_runtime_mutex
);
84 while (i
< method_list
->method_count
)
86 Method method
= &method_list
->method_list
[i
];
87 if (method
->method_name
)
90 = __sel_register_typed_name ((const char *) method
->method_name
,
91 method
->method_types
, 0, YES
);
95 objc_mutex_unlock (__objc_runtime_mutex
);
98 /* The same as __objc_register_selectors_from_list, but works on a
99 struct objc_method_description_list* instead of a struct
100 objc_method_list*. This is only used for protocols, which have
101 lists of method descriptions, not methods. */
103 __objc_register_selectors_from_description_list
104 (struct objc_method_description_list
*method_list
)
108 objc_mutex_lock (__objc_runtime_mutex
);
109 while (i
< method_list
->count
)
111 struct objc_method_description
*method
= &method_list
->list
[i
];
115 = __sel_register_typed_name ((const char *) method
->name
,
116 method
->types
, 0, YES
);
120 objc_mutex_unlock (__objc_runtime_mutex
);
123 /* Register instance methods as class methods for root classes. */
124 void __objc_register_instance_methods_to_class (Class
class)
126 struct objc_method_list
*method_list
;
127 struct objc_method_list
*class_method_list
;
128 int max_methods_no
= 16;
129 struct objc_method_list
*new_list
;
132 /* Only if a root class. */
133 if (class->super_class
)
136 /* Allocate a method list to hold the new class methods. */
137 new_list
= objc_calloc (sizeof (struct objc_method_list
)
138 + sizeof (struct objc_method
[max_methods_no
]), 1);
139 method_list
= class->methods
;
140 class_method_list
= class->class_pointer
->methods
;
141 curr_method
= &new_list
->method_list
[0];
143 /* Iterate through the method lists for the class. */
148 /* Iterate through the methods from this method list. */
149 for (i
= 0; i
< method_list
->method_count
; i
++)
151 Method mth
= &method_list
->method_list
[i
];
153 && ! search_for_method_in_list (class_method_list
,
156 /* This instance method isn't a class method. Add it
157 into the new_list. */
160 /* Reallocate the method list if necessary. */
161 if (++new_list
->method_count
== max_methods_no
)
163 objc_realloc (new_list
, sizeof (struct objc_method_list
)
165 objc_method
[max_methods_no
+= 16]));
166 curr_method
= &new_list
->method_list
[new_list
->method_count
];
170 method_list
= method_list
->method_next
;
173 /* If we created any new class methods then attach the method list
175 if (new_list
->method_count
)
178 objc_realloc (new_list
, sizeof (struct objc_method_list
)
179 + sizeof (struct objc_method
[new_list
->method_count
]));
180 new_list
->method_next
= class->class_pointer
->methods
;
181 class->class_pointer
->methods
= new_list
;
186 __objc_update_dispatch_table_for_class (class->class_pointer
);
190 sel_isEqual (SEL s1
, SEL s2
)
192 if (s1
== 0 || s2
== 0)
195 return s1
->sel_id
== s2
->sel_id
;
198 /* Return YES iff t1 and t2 have same method types. Ignore the
201 sel_types_match (const char *t1
, const char *t2
)
207 if (*t1
== '+') t1
++;
208 if (*t2
== '+') t2
++;
209 while (isdigit ((unsigned char) *t1
)) t1
++;
210 while (isdigit ((unsigned char) *t2
)) t2
++;
211 /* xxx Remove these next two lines when qualifiers are put in
212 all selectors, not just Protocol selectors. */
213 t1
= objc_skip_type_qualifiers (t1
);
214 t2
= objc_skip_type_qualifiers (t2
);
225 /* Return selector representing name. */
227 sel_get_typed_uid (const char *name
, const char *types
)
232 objc_mutex_lock (__objc_runtime_mutex
);
234 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
237 objc_mutex_unlock (__objc_runtime_mutex
);
241 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
244 SEL s
= (SEL
) l
->head
;
245 if (types
== 0 || s
->sel_types
== 0)
247 if (s
->sel_types
== types
)
249 objc_mutex_unlock (__objc_runtime_mutex
);
253 else if (sel_types_match (s
->sel_types
, types
))
255 objc_mutex_unlock (__objc_runtime_mutex
);
260 objc_mutex_unlock (__objc_runtime_mutex
);
264 /* Return selector representing name; prefer a selector with non-NULL
267 sel_get_any_typed_uid (const char *name
)
273 objc_mutex_lock (__objc_runtime_mutex
);
275 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
278 objc_mutex_unlock (__objc_runtime_mutex
);
282 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
288 objc_mutex_unlock (__objc_runtime_mutex
);
293 objc_mutex_unlock (__objc_runtime_mutex
);
297 /* Return selector representing name. */
299 sel_get_any_uid (const char *name
)
304 objc_mutex_lock (__objc_runtime_mutex
);
306 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
307 if (soffset_decode (i
) == 0)
309 objc_mutex_unlock (__objc_runtime_mutex
);
313 l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
314 objc_mutex_unlock (__objc_runtime_mutex
);
319 return (SEL
) l
->head
;
322 /* Get the name of a selector. If the selector is unknown, the empty
323 string "" is returned. */
324 const char *sel_getName (SEL selector
)
328 if (selector
== NULL
)
329 return "<null selector>";
331 objc_mutex_lock (__objc_runtime_mutex
);
332 if ((soffset_decode ((sidx
)selector
->sel_id
) > 0)
333 && (soffset_decode ((sidx
)selector
->sel_id
) <= __objc_selector_max_index
))
334 ret
= sarray_get_safe (__objc_selector_names
, (sidx
) selector
->sel_id
);
337 objc_mutex_unlock (__objc_runtime_mutex
);
341 /* Traditional GNU Objective-C Runtime API. */
342 const char *sel_get_name (SEL selector
)
344 if (selector
== NULL
)
347 return sel_getName (selector
);
351 sel_is_mapped (SEL selector
)
353 unsigned int idx
= soffset_decode ((sidx
)selector
->sel_id
);
354 return ((idx
> 0) && (idx
<= __objc_selector_max_index
));
357 const char *sel_getType (SEL selector
)
360 return selector
->sel_types
;
365 /* Traditional GNU Objective-C Runtime API. */
366 const char *sel_get_type (SEL selector
)
368 return sel_getType (selector
);
371 /* The uninstalled dispatch table. */
372 extern struct sarray
*__objc_uninstalled_dtable
;
374 /* __sel_register_typed_name allocates lots of struct objc_selector:s
375 of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the
376 number of malloc calls and memory lost to malloc overhead, we
377 allocate objc_selector:s in blocks here. This is only called from
378 __sel_register_typed_name, and __sel_register_typed_name may only
379 be called when __objc_runtime_mutex is locked.
381 Note that the objc_selector:s allocated from
382 __sel_register_typed_name are never freed.
384 62 because 62 * sizeof (struct objc_selector) = 496 (992). This
385 should let malloc add some overhead and use a nice, round 512
386 (1024) byte chunk. */
387 #define SELECTOR_POOL_SIZE 62
388 static struct objc_selector
*selector_pool
;
389 static int selector_pool_left
;
391 static struct objc_selector
*
392 pool_alloc_selector(void)
394 if (!selector_pool_left
)
396 selector_pool
= objc_malloc (sizeof (struct objc_selector
)
397 * SELECTOR_POOL_SIZE
);
398 selector_pool_left
= SELECTOR_POOL_SIZE
;
400 return &selector_pool
[--selector_pool_left
];
403 /* Store the passed selector name in the selector record and return
404 its selector value (value returned by sel_get_uid). Assume that
405 the calling function has locked down __objc_runtime_mutex. The
406 is_const parameter tells us if the name and types parameters are
407 really constant or not. If YES then they are constant and we can
408 just store the pointers. If NO then we need to copy name and types
409 because the pointers may disappear later on. */
411 __sel_register_typed_name (const char *name
, const char *types
,
412 struct objc_selector
*orig
, BOOL is_const
)
414 struct objc_selector
*j
;
418 i
= (sidx
) objc_hash_value_for_key (__objc_selector_hash
, name
);
419 if (soffset_decode (i
) != 0)
421 for (l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
424 SEL s
= (SEL
) l
->head
;
425 if (types
== 0 || s
->sel_types
== 0)
427 if (s
->sel_types
== types
)
431 orig
->sel_id
= (void *) i
;
438 else if (! strcmp (s
->sel_types
, types
))
442 orig
->sel_id
= (void *) i
;
452 j
= pool_alloc_selector ();
454 j
->sel_id
= (void *) i
;
455 /* Can we use the pointer or must copy types? Don't copy if
457 if ((is_const
) || (types
== 0))
458 j
->sel_types
= (const char *) types
;
461 j
->sel_types
= (char *) objc_malloc (strlen (types
) + 1);
462 strcpy ((char *) j
->sel_types
, types
);
464 l
= (struct objc_list
*) sarray_get_safe (__objc_selector_array
, i
);
468 __objc_selector_max_index
+= 1;
469 i
= soffset_encode (__objc_selector_max_index
);
473 j
= pool_alloc_selector ();
475 j
->sel_id
= (void *) i
;
476 /* Can we use the pointer or must copy types? Don't copy if
478 if ((is_const
) || (types
== 0))
479 j
->sel_types
= (const char *) types
;
482 j
->sel_types
= (char *) objc_malloc (strlen (types
) + 1);
483 strcpy ((char *) j
->sel_types
, types
);
488 DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name
, types
,
489 (long) soffset_decode (i
));
492 int is_new
= (l
== 0);
493 const char *new_name
;
495 /* Can we use the pointer or must copy name? Don't copy if
497 if ((is_const
) || (name
== 0))
501 new_name
= (char *) objc_malloc (strlen (name
) + 1);
502 strcpy ((char *) new_name
, name
);
505 l
= list_cons ((void *) j
, l
);
506 sarray_at_put_safe (__objc_selector_names
, i
, (void *) new_name
);
507 sarray_at_put_safe (__objc_selector_array
, i
, (void *) l
);
509 objc_hash_add (&__objc_selector_hash
, (void *) new_name
, (void *) i
);
512 sarray_realloc (__objc_uninstalled_dtable
, __objc_selector_max_index
+ 1);
518 sel_registerName (const char *name
)
522 objc_mutex_lock (__objc_runtime_mutex
);
523 /* Assume that name is not constant static memory and needs to be
524 copied before put into a runtime structure. is_const == NO. */
525 ret
= __sel_register_typed_name (name
, 0, 0, NO
);
526 objc_mutex_unlock (__objc_runtime_mutex
);
531 /* Traditional GNU Objective-C Runtime API. */
533 sel_register_name (const char *name
)
535 return sel_registerName (name
);
539 sel_registerTypedName (const char *name
, const char *type
)
543 objc_mutex_lock (__objc_runtime_mutex
);
544 /* Assume that name and type are not constant static memory and need
545 to be copied before put into a runtime structure. is_const ==
547 ret
= __sel_register_typed_name (name
, type
, 0, NO
);
548 objc_mutex_unlock (__objc_runtime_mutex
);
554 sel_register_typed_name (const char *name
, const char *type
)
556 return sel_registerTypedName (name
, type
);
559 /* Return the selector representing name. */
561 sel_getUid (const char *name
)
563 return sel_registerTypedName (name
, 0);
566 /* Traditional GNU Objective-C Runtime API. */
568 sel_get_uid (const char *name
)
570 return sel_getUid (name
);